├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── Assets ├── Android64.png ├── ClearScreen.jpg ├── ColoredTriangle.jpg ├── ComputeParticles.jpg ├── Linux64.png ├── MacOS64.png ├── TexturedCube.jpg ├── Ubuntu64.png ├── Vulkan64.png └── Windows64.png ├── LICENSE ├── README.md ├── Samples ├── Android │ ├── 01-ClearScreen │ │ ├── 01-ClearScreen.csproj │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ │ ├── Resource.Designer.cs │ │ │ ├── drawable │ │ │ └── Icon.png │ │ │ ├── layout │ │ │ └── Main.axml │ │ │ └── values │ │ │ └── Strings.xml │ ├── 02-ColoredTriangle │ │ ├── 02-ColoredTriangle.csproj │ │ ├── Assets │ │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ │ ├── AboutResources.txt │ │ │ ├── Resource.Designer.cs │ │ │ ├── drawable │ │ │ └── Icon.png │ │ │ ├── layout │ │ │ └── Main.axml │ │ │ └── values │ │ │ └── Strings.xml │ ├── 03-TexturedCube │ │ ├── 03-TexturedCube.csproj │ │ ├── Assets │ │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ │ ├── AboutResources.txt │ │ │ ├── Resource.Designer.cs │ │ │ ├── drawable │ │ │ └── Icon.png │ │ │ ├── layout │ │ │ └── Main.axml │ │ │ └── values │ │ │ └── Strings.xml │ └── 04-ComputeParticles │ │ ├── 04-ComputeParticles.csproj │ │ ├── Assets │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.Designer.cs │ │ ├── drawable │ │ └── Icon.png │ │ ├── layout │ │ └── Main.axml │ │ └── values │ │ └── Strings.xml ├── MacOS │ ├── 01-ClearScreen │ │ ├── 01-ClearScreen.csproj │ │ └── Program.cs │ ├── 02-ColoredTriangle │ │ ├── 02-ColoredTriangle.csproj │ │ └── Program.cs │ ├── 03-TexturedCube │ │ ├── 03-TexturedCube.csproj │ │ └── Program.cs │ └── 04-ComputeParticles │ │ ├── 04-ComputeParticles.csproj │ │ └── Program.cs ├── MiniFramework │ ├── ContentLoaders │ │ ├── KtxVulkanImage.cs │ │ └── ShaderModule.cs │ ├── ContentManager.cs │ ├── GeometricPrimitive.cs │ ├── MiniFramework.csproj │ ├── Timer.cs │ ├── VulkanApp.cs │ ├── VulkanBuffer.cs │ ├── VulkanContext.cs │ └── VulkanImage.cs ├── Shared │ ├── 01-ClearScreen │ │ └── ClearScreenApp.cs │ ├── 02-ColoredTriangle │ │ ├── ColoredTriangleApp.cs │ │ └── Content │ │ │ ├── CompileShaders.bat │ │ │ ├── Shader.frag │ │ │ ├── Shader.frag.spv │ │ │ ├── Shader.vert │ │ │ └── Shader.vert.spv │ ├── 03-TexturedCube │ │ ├── Content │ │ │ ├── CompileShaders.bat │ │ │ ├── IndustryForgedDark512.ktx │ │ │ ├── Shader.frag │ │ │ ├── Shader.frag.spv │ │ │ ├── Shader.vert │ │ │ └── Shader.vert.spv │ │ └── TexturedCubeApp.cs │ ├── 04-ComputeParticles │ │ ├── ComputeParticlesApp.cs │ │ └── Content │ │ │ ├── CompileShaders.bat │ │ │ ├── ParticleDiffuse.ktx │ │ │ ├── Shader.comp │ │ │ ├── Shader.comp.spv │ │ │ ├── Shader.frag │ │ │ ├── Shader.frag.spv │ │ │ ├── Shader.vert │ │ │ └── Shader.vert.spv │ ├── MacOSWindow.cs │ ├── NativeMacOS │ │ ├── NativeMacOS.dll │ │ └── libmacwindow.dylib │ ├── System.Numerics.Vectors.dll │ ├── VulkanSurfaceView.cs │ └── Win32Window.cs └── Win32 │ ├── 01-ClearScreen │ ├── 01-ClearScreen.csproj │ └── Program.cs │ ├── 02-ColoredTriangle │ ├── 02-ColoredTriangle.csproj │ └── Program.cs │ ├── 03-TexturedCube │ ├── 03-TexturedCube.csproj │ └── Program.cs │ └── 04-ComputeParticles │ ├── 04-ComputeParticles.csproj │ └── Program.cs ├── Src ├── AllocationCallbacks.cs ├── Amd │ ├── CommandBufferExtensions.cs │ └── PipelineExtensions.cs ├── Android │ ├── DeviceExtensions.cs │ ├── ImageExtensions.cs │ └── QueueExtensions.cs ├── Bool.cs ├── Buffer.cs ├── BufferView.cs ├── Color.cs ├── CommandBuffer.cs ├── CommandPool.cs ├── Constant.cs ├── DescriptorPool.cs ├── DescriptorSet.cs ├── DescriptorSetLayout.cs ├── Device.cs ├── DeviceMemory.cs ├── Event.cs ├── Ext │ ├── CommandBufferExtensions.cs │ ├── DebugReportCallbackExt.cs │ ├── DeviceExtensions.cs │ ├── DisplayKhrExtensions.cs │ ├── InstanceExtensions.cs │ ├── PhysicalDeviceExtensions.cs │ ├── PipelineExtensions.cs │ ├── SamplerExtensions.cs │ ├── ShaderModuleExtensions.cs │ ├── SwapchainKhrExtensions.cs │ └── ValidationCacheExt.cs ├── Extent.cs ├── Fence.cs ├── Format.cs ├── Framebuffer.cs ├── Google │ └── SwapchainKhrExtensions.cs ├── Handle.cs ├── Image.cs ├── ImageView.cs ├── Instance.cs ├── Interop.cs ├── Khr │ ├── CommandBufferExtensions.cs │ ├── CommandPoolExtensions.cs │ ├── DescriptorSetExtensions.cs │ ├── DescriptorUpdateTemplateKhr.cs │ ├── DeviceExtensions.cs │ ├── DeviceMemoryExtensions.cs │ ├── DisplayKhr.cs │ ├── DisplayModeKhr.cs │ ├── InstanceExtensions.cs │ ├── PhysicalDeviceExtensions.cs │ ├── QueueExtensions.cs │ ├── SamplerYcbcrConversionKhr.cs │ ├── SemaphoreExtensions.cs │ ├── SurfaceKhr.cs │ └── SwapchainKhr.cs ├── Khx │ ├── CommandBufferExtensions.cs │ ├── DeviceExtensions.cs │ ├── DeviceMemoryExtensions.cs │ ├── InstanceExtensions.cs │ └── PhysicalDeviceExtensions.cs ├── Mvk │ ├── DeviceExtensions.cs │ ├── InstanceExtensions.cs │ └── MVKDeviceConfiguration.cs ├── NN │ └── InstanceExtensions.cs ├── NV │ ├── CommandBufferExtensions.cs │ ├── DeviceMemoryExtensions.cs │ ├── PhysicalDeviceExtensions.cs │ └── PipelineExtensions.cs ├── Nvx │ ├── CommandBufferExtensions.cs │ ├── DeviceExtensions.cs │ ├── IndirectCommandsLayoutNvx.cs │ ├── ObjectTableNvx.cs │ └── PhysicalDeviceExtensions.cs ├── ObjectType.cs ├── Offset.cs ├── PhysicalDevice.cs ├── Pipeline.cs ├── PipelineCache.cs ├── PipelineLayout.cs ├── QueryPool.cs ├── Queue.cs ├── Rect.cs ├── RenderPass.cs ├── Result.cs ├── Sampler.cs ├── Semaphore.cs ├── ShaderModule.cs ├── Size.cs ├── StructureType.cs ├── UtilityExtensions.cs ├── Version.cs ├── VulkanCore.csproj ├── VulkanException.cs └── VulkanLibrary.cs ├── Tests ├── BoolTest.cs ├── BufferTest.cs ├── CommandBufferTest.cs ├── Content │ ├── Shader.comp │ ├── Shader.comp.spv │ ├── Shader.frag │ ├── Shader.frag.spv │ ├── Shader.vert │ └── Shader.vert.spv ├── DescriptorSetTest.cs ├── DeviceMemoryTest.cs ├── DeviceTest.cs ├── EventTest.cs ├── ExtentTest.cs ├── FenceTest.cs ├── ImageTest.cs ├── InstanceTest.cs ├── InteropTest.cs ├── Issues │ └── KhxDeviceGroupCreationTest.cs ├── OffsetTest.cs ├── PhysicalDeviceTest.cs ├── PipelineCacheTest.cs ├── QueryTest.cs ├── QueueTest.cs ├── RectTest.cs ├── RenderPassTest.cs ├── SizeTest.cs ├── Utilities │ ├── DefaultHandles.cs │ └── HandleTestBase.cs ├── UtilityTest.cs ├── VersionTest.cs └── VulkanCore.Tests.csproj └── VulkanCore.sln /.editorconfig: -------------------------------------------------------------------------------- 1 | ; Topmost EditorConfig file. 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | indent_brace_style = Allman ; Not part of the standard but some tools do support it. 11 | 12 | ; VS 2017 references: 13 | ; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options 14 | ; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | 3 | os: 4 | - osx 5 | - linux 6 | 7 | # .NET CLI requires Ubuntu 14.04. 8 | sudo: required 9 | dist: trusty 10 | 11 | # .NET CLI requires OSX 10.10. 12 | osx_image: xcode8.3 13 | 14 | mono: none 15 | dotnet: 2.0.0 16 | 17 | script: 18 | - ulimit -n 4096 19 | - dotnet build Src/VulkanCore.csproj 20 | - dotnet build Tests/VulkanCore.Tests.csproj 21 | -------------------------------------------------------------------------------- /Assets/Android64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/Android64.png -------------------------------------------------------------------------------- /Assets/ClearScreen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/ClearScreen.jpg -------------------------------------------------------------------------------- /Assets/ColoredTriangle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/ColoredTriangle.jpg -------------------------------------------------------------------------------- /Assets/ComputeParticles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/ComputeParticles.jpg -------------------------------------------------------------------------------- /Assets/Linux64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/Linux64.png -------------------------------------------------------------------------------- /Assets/MacOS64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/MacOS64.png -------------------------------------------------------------------------------- /Assets/TexturedCube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/TexturedCube.jpg -------------------------------------------------------------------------------- /Assets/Ubuntu64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/Ubuntu64.png -------------------------------------------------------------------------------- /Assets/Vulkan64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/Vulkan64.png -------------------------------------------------------------------------------- /Assets/Windows64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Assets/Windows64.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jaanus Varus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VulkanCore 2 | 3 | [![NuGet Pre Release](https://img.shields.io/nuget/vpre/VulkanCore.svg)](https://www.nuget.org/packages/VulkanCore) 4 | [![Vulkan](https://img.shields.io/badge/vulkan-1.0.69-brightgreen.svg)](https://www.khronos.org/vulkan/) 5 | [![.NET Standard](https://img.shields.io/badge/netstandard-1.3-brightgreen.svg)](https://github.com/dotnet/standard/blob/master/docs/versions.md) 6 | [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/discosultan/vulkancore.svg?label=windows)](https://ci.appveyor.com/project/discosultan/vulkancore) 7 | [![Travis Build Status](https://img.shields.io/travis/discosultan/VulkanCore.svg?label=unix)](https://travis-ci.org/discosultan/VulkanCore) 8 | 9 | > :warning: This project is no longer in active development. It fully implements the latest 1.0 version of Vulkan. Bugs in the core project will still be fixed and contributions for versions 1.1 and 1.2+ are welcome. Please see the "Related Work" list below for alternatives. 10 | 11 | - [Introduction](#introduction) 12 | - [Building](#building) 13 | - [Samples](#samples---) 14 | - [Tests](#tests--) 15 | - [Related Work](#related-work) 16 | 17 | ## Introduction 18 | 19 | VulkanCore is a thin cross-platform object-oriented wrapper around the Vulkan C API. It supports .NET Core, .NET Framework and Mono. 20 | 21 | **Why yet another set of bindings?** While most of the alternatives use a generator-based approach, these bindings do not. This means: 22 | 23 | Pros: 24 | - Full control over the API including high quality code documentation 25 | - Easier to contribute - no need to understand a generator 26 | 27 | Cons: 28 | - Requires manual work to keep up to date with the Vulkan API registry 29 | - Cumbersome to modify the fundamentals - impossible to simply regenerate everything 30 | 31 | ## Building 32 | 33 | [Visual Studio 2017](https://www.visualstudio.com/vs/whatsnew/) or equivalent tooling is required to successfully compile the source. The tooling must support the *new .csproj format* and *C# 7* language features. Latest [Rider](https://www.jetbrains.com/rider/), [Visual Studio Code](https://code.visualstudio.com/) or [MonoDevelop](http://www.monodevelop.com/) should all work but have not been tested. 34 | 35 | ## Samples 36 | 37 | Vulkan-capable graphics hardware and drivers are required to run the samples. Win32 samples are based on WinForms (.NET Framework) and Android ones on Xamarin (Mono). 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 67 | 68 |
ClearScreen 43 | ClearScreen 44 |

Sets up a window and clears it to a solid color

45 |
ColoredTriangle 50 | ColoredTriangle 51 |

Renders a colored triangle defined in a vertex shader

52 |
TexturedCube 57 | TexturedCube 58 |

Creates a rotating textured cube mesh

59 |
ComputeParticles 64 | ComputeParticles 65 |

Simulates 2D particles using a compute shader

66 |
69 | 70 | ## Tests 71 | 72 | In order to provide a certain level of *functional correctness*, the project aims to achieve *full statement coverage* for the *core API*. Tests are built using [xUnit](https://xunit.github.io/) and .NET Core and have been tested on Ubuntu and Windows platforms. 73 | 74 | Note that it's difficult to test vendor specific extensions due to requirements for specialized hardware/drivers - therefore, covering them at this point is not planned. 75 | 76 | ## Related Work 77 | 78 | - [VulkanSharp](https://github.com/mono/VulkanSharp) 79 | - [SharpVulkan](https://github.com/jwollen/SharpVulkan) 80 | - [SharpVk](https://github.com/FacticiusVir/SharpVk) 81 | - [vk](https://github.com/mellinoe/vk) 82 | - [Vortice.Vulkan](https://github.com/amerkoleci/Vortice.Vulkan) 83 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace VulkanCore.Samples.ClearScreen 6 | { 7 | [Activity( 8 | Label = "ClearScreen", 9 | ScreenOrientation = ScreenOrientation.SensorPortrait, 10 | MainLauncher = true, 11 | Icon = "@drawable/icon")] 12 | public class MainActivity : Activity 13 | { 14 | protected override void OnCreate(Bundle bundle) 15 | { 16 | base.OnCreate(bundle); 17 | var surfaceView = new VulkanSurfaceView(this, new ClearScreenApp()); 18 | SetContentView(surfaceView); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("_01_ClearScreen")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("01-ClearScreen")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.42000 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("VulkanCore.Samples.ClearScreen.Resource", IsApplication=true)] 13 | 14 | namespace VulkanCore.Samples.ClearScreen 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public static void UpdateIdValues() 28 | { 29 | } 30 | 31 | public partial class Attribute 32 | { 33 | 34 | static Attribute() 35 | { 36 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 37 | } 38 | 39 | private Attribute() 40 | { 41 | } 42 | } 43 | 44 | public partial class Drawable 45 | { 46 | 47 | // aapt resource value: 0x7f020000 48 | public const int Icon = 2130837504; 49 | 50 | static Drawable() 51 | { 52 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 53 | } 54 | 55 | private Drawable() 56 | { 57 | } 58 | } 59 | 60 | public partial class Id 61 | { 62 | 63 | // aapt resource value: 0x7f050000 64 | public const int Layout = 2131034112; 65 | 66 | static Id() 67 | { 68 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 69 | } 70 | 71 | private Id() 72 | { 73 | } 74 | } 75 | 76 | public partial class Layout 77 | { 78 | 79 | // aapt resource value: 0x7f030000 80 | public const int Main = 2130903040; 81 | 82 | static Layout() 83 | { 84 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 85 | } 86 | 87 | private Layout() 88 | { 89 | } 90 | } 91 | 92 | public partial class String 93 | { 94 | 95 | // aapt resource value: 0x7f040001 96 | public const int ApplicationName = 2130968577; 97 | 98 | // aapt resource value: 0x7f040000 99 | public const int Hello = 2130968576; 100 | 101 | static String() 102 | { 103 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 104 | } 105 | 106 | private String() 107 | { 108 | } 109 | } 110 | } 111 | } 112 | #pragma warning restore 1591 113 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Resources/drawable/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Android/01-ClearScreen/Resources/drawable/Icon.png -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Samples/Android/01-ClearScreen/Resources/values/Strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World, Click Me! 4 | 01-ClearScreen 5 | 6 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace VulkanCore.Samples.ColoredTriangle 6 | { 7 | [Activity( 8 | Label = "ColoredTriangle", 9 | ScreenOrientation = ScreenOrientation.SensorPortrait, 10 | MainLauncher = true, 11 | Icon = "@drawable/icon")] 12 | public class MainActivity : Activity 13 | { 14 | protected override void OnCreate(Bundle bundle) 15 | { 16 | base.OnCreate(bundle); 17 | var surfaceView = new VulkanSurfaceView(this, new ColoredTriangleApp()); 18 | SetContentView(surfaceView); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ColoredTriangle")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ColoredTriangle")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.42000 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("VulkanCore.Samples.ColoredTriangle.Resource", IsApplication=true)] 13 | 14 | namespace VulkanCore.Samples.ColoredTriangle 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public static void UpdateIdValues() 28 | { 29 | } 30 | 31 | public partial class Attribute 32 | { 33 | 34 | static Attribute() 35 | { 36 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 37 | } 38 | 39 | private Attribute() 40 | { 41 | } 42 | } 43 | 44 | public partial class Drawable 45 | { 46 | 47 | // aapt resource value: 0x7f020000 48 | public const int Icon = 2130837504; 49 | 50 | static Drawable() 51 | { 52 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 53 | } 54 | 55 | private Drawable() 56 | { 57 | } 58 | } 59 | 60 | public partial class Layout 61 | { 62 | 63 | // aapt resource value: 0x7f030000 64 | public const int Main = 2130903040; 65 | 66 | static Layout() 67 | { 68 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 69 | } 70 | 71 | private Layout() 72 | { 73 | } 74 | } 75 | 76 | public partial class String 77 | { 78 | 79 | // aapt resource value: 0x7f040001 80 | public const int ApplicationName = 2130968577; 81 | 82 | // aapt resource value: 0x7f040000 83 | public const int Hello = 2130968576; 84 | 85 | static String() 86 | { 87 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 88 | } 89 | 90 | private String() 91 | { 92 | } 93 | } 94 | } 95 | } 96 | #pragma warning restore 1591 97 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Resources/drawable/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Android/02-ColoredTriangle/Resources/drawable/Icon.png -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /Samples/Android/02-ColoredTriangle/Resources/values/Strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World, Click Me! 4 | ColoredTriangle 5 | 6 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.OS; 3 | using Android.Content.PM; 4 | 5 | namespace VulkanCore.Samples.TexturedCube 6 | { 7 | [Activity( 8 | Label = "TexturedCube", 9 | ScreenOrientation = ScreenOrientation.SensorPortrait, 10 | MainLauncher = true, 11 | Icon = "@drawable/icon")] 12 | public class MainActivity : Activity 13 | { 14 | protected override void OnCreate(Bundle bundle) 15 | { 16 | base.OnCreate(bundle); 17 | var surfaceView = new VulkanSurfaceView(this, new TexturedCubeApp()); 18 | SetContentView(surfaceView); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("_03_TexturedCube")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("03-TexturedCube")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.42000 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("VulkanCore.Samples.TexturedCube.Resource", IsApplication=true)] 13 | 14 | namespace VulkanCore.Samples.TexturedCube 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public static void UpdateIdValues() 28 | { 29 | } 30 | 31 | public partial class Attribute 32 | { 33 | 34 | static Attribute() 35 | { 36 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 37 | } 38 | 39 | private Attribute() 40 | { 41 | } 42 | } 43 | 44 | public partial class Drawable 45 | { 46 | 47 | // aapt resource value: 0x7f020000 48 | public const int Icon = 2130837504; 49 | 50 | static Drawable() 51 | { 52 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 53 | } 54 | 55 | private Drawable() 56 | { 57 | } 58 | } 59 | 60 | public partial class Layout 61 | { 62 | 63 | // aapt resource value: 0x7f030000 64 | public const int Main = 2130903040; 65 | 66 | static Layout() 67 | { 68 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 69 | } 70 | 71 | private Layout() 72 | { 73 | } 74 | } 75 | 76 | public partial class String 77 | { 78 | 79 | // aapt resource value: 0x7f040001 80 | public const int ApplicationName = 2130968577; 81 | 82 | // aapt resource value: 0x7f040000 83 | public const int Hello = 2130968576; 84 | 85 | static String() 86 | { 87 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 88 | } 89 | 90 | private String() 91 | { 92 | } 93 | } 94 | } 95 | } 96 | #pragma warning restore 1591 97 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Resources/drawable/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Android/03-TexturedCube/Resources/drawable/Icon.png -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /Samples/Android/03-TexturedCube/Resources/values/Strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World, Click Me! 4 | 03-TexturedCube 5 | 6 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace VulkanCore.Samples.ComputeParticles 6 | { 7 | [Activity( 8 | Label = "ComputeParticles", 9 | ScreenOrientation = ScreenOrientation.SensorPortrait, 10 | MainLauncher = true, 11 | Icon = "@drawable/icon")] 12 | public class MainActivity : Activity 13 | { 14 | protected override void OnCreate(Bundle bundle) 15 | { 16 | base.OnCreate(bundle); 17 | var surfaceView = new VulkanSurfaceView(this, new ComputeParticlesApp()); 18 | SetContentView(surfaceView); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("_04_ComputeParticles")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("DLM")] 13 | [assembly: AssemblyProduct("04-ComputeParticles")] 14 | [assembly: AssemblyCopyright("Copyright © DLM 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by a tool. 5 | // Runtime Version:4.0.30319.42000 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | //------------------------------------------------------------------------------ 11 | 12 | [assembly: global::Android.Runtime.ResourceDesignerAttribute("VulkanCore.Samples.ComputeParticles.Resource", IsApplication=true)] 13 | 14 | namespace VulkanCore.Samples.ComputeParticles 15 | { 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] 19 | public partial class Resource 20 | { 21 | 22 | static Resource() 23 | { 24 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 25 | } 26 | 27 | public static void UpdateIdValues() 28 | { 29 | } 30 | 31 | public partial class Attribute 32 | { 33 | 34 | static Attribute() 35 | { 36 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 37 | } 38 | 39 | private Attribute() 40 | { 41 | } 42 | } 43 | 44 | public partial class Drawable 45 | { 46 | 47 | // aapt resource value: 0x7f020000 48 | public const int Icon = 2130837504; 49 | 50 | static Drawable() 51 | { 52 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 53 | } 54 | 55 | private Drawable() 56 | { 57 | } 58 | } 59 | 60 | public partial class Layout 61 | { 62 | 63 | // aapt resource value: 0x7f030000 64 | public const int Main = 2130903040; 65 | 66 | static Layout() 67 | { 68 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 69 | } 70 | 71 | private Layout() 72 | { 73 | } 74 | } 75 | 76 | public partial class String 77 | { 78 | 79 | // aapt resource value: 0x7f040001 80 | public const int ApplicationName = 2130968577; 81 | 82 | // aapt resource value: 0x7f040000 83 | public const int Hello = 2130968576; 84 | 85 | static String() 86 | { 87 | global::Android.Runtime.ResourceIdManager.UpdateIdValues(); 88 | } 89 | 90 | private String() 91 | { 92 | } 93 | } 94 | } 95 | } 96 | #pragma warning restore 1591 97 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Resources/drawable/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Android/04-ComputeParticles/Resources/drawable/Icon.png -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /Samples/Android/04-ComputeParticles/Resources/values/Strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World, Click Me! 4 | 04-ComputeParticles 5 | 6 | -------------------------------------------------------------------------------- /Samples/MacOS/01-ClearScreen/01-ClearScreen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | true 7 | false 8 | 9 | 10 | 11 | 12 | 13 | ClearScreenApp.cs 14 | 15 | 16 | 17 | MacOSWindow.cs 18 | 19 | 20 | 21 | {1772437f-982d-4edf-80e8-11b826219041} 22 | VulkanCore 23 | 24 | 25 | 26 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 27 | MiniFramework 28 | 29 | 30 | 31 | ..\..\Shared\NativeMacOS\NativeMacOS.dll 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Samples/MacOS/01-ClearScreen/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ClearScreen 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new MacOSWindow( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ClearScreenApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/MacOS/02-ColoredTriangle/02-ColoredTriangle.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | true 7 | false 8 | 9 | 10 | 11 | 12 | 13 | ColoredTriangleApp.cs 14 | 15 | 16 | 17 | Content\CompileShaders.bat 18 | 19 | 20 | Content\Shader.frag 21 | 22 | 23 | Content\Shader.frag.spv 24 | PreserveNewest 25 | 26 | 27 | Content\Shader.vert 28 | 29 | 30 | Content\Shader.vert.spv 31 | PreserveNewest 32 | 33 | 34 | 35 | MacOSWindow.cs 36 | 37 | 38 | 39 | {1772437f-982d-4edf-80e8-11b826219041} 40 | VulkanCore 41 | 42 | 43 | 44 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 45 | MiniFramework 46 | 47 | 48 | 49 | ..\..\Shared/NativeMacOS/NativeMacOS.dll 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Samples/MacOS/02-ColoredTriangle/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ColoredTriangle 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new MacOSWindow( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ColoredTriangleApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/MacOS/03-TexturedCube/03-TexturedCube.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | true 7 | false 8 | 9 | 10 | 11 | 12 | 13 | TexturedCubeApp.cs 14 | 15 | 16 | 17 | Content\Shader.frag 18 | 19 | 20 | Content\Shader.frag.spv 21 | PreserveNewest 22 | 23 | 24 | Content\Shader.vert 25 | 26 | 27 | Content\Shader.vert.spv 28 | PreserveNewest 29 | 30 | 31 | Content\IndustryForgedDark512.ktx 32 | PreserveNewest 33 | 34 | 35 | 36 | MacOSWindow.cs 37 | 38 | 39 | 40 | {1772437f-982d-4edf-80e8-11b826219041} 41 | VulkanCore 42 | 43 | 44 | 45 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 46 | MiniFramework 47 | 48 | 49 | 50 | ..\..\Shared\NativeMacOS\NativeMacOS.dll 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Samples/MacOS/03-TexturedCube/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.TexturedCube 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new MacOSWindow( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new TexturedCubeApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/MacOS/04-ComputeParticles/04-ComputeParticles.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | true 7 | false 8 | 9 | 10 | 11 | 12 | 13 | ComputeParticlesApp.cs 14 | 15 | 16 | 17 | Content\CompileShaders.bat 18 | 19 | 20 | Content\Shader.comp 21 | 22 | 23 | Content\Shader.comp.spv 24 | PreserveNewest 25 | 26 | 27 | Content\Shader.frag 28 | 29 | 30 | Content\Shader.frag.spv 31 | PreserveNewest 32 | 33 | 34 | Content\Shader.vert 35 | 36 | 37 | Content\Shader.vert.spv 38 | PreserveNewest 39 | 40 | 41 | Content\ParticleDiffuse.ktx 42 | PreserveNewest 43 | 44 | 45 | 46 | MacOSWindow.cs 47 | 48 | 49 | 50 | {1772437f-982d-4edf-80e8-11b826219041} 51 | VulkanCore 52 | 53 | 54 | 55 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 56 | MiniFramework 57 | 58 | 59 | 60 | ..\..\Shared\NativeMacOS\NativeMacOS.dll 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Samples/MacOS/04-ComputeParticles/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ComputeParticles 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new MacOSWindow( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ComputeParticlesApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/MiniFramework/ContentLoaders/KtxVulkanImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace VulkanCore.Samples.ContentLoaders 7 | { 8 | internal static partial class Loader 9 | { 10 | // Ktx spec: https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ 11 | 12 | private static readonly byte[] KtxIdentifier = 13 | { 14 | 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A 15 | }; 16 | 17 | // OpenGL internal color formats are described in table 8.12 at 18 | // https://khronos.org/registry/OpenGL/specs/gl/glspec44.core.pdf 19 | private static readonly Dictionary _glInternalFormatToVkFormat = new Dictionary() 20 | { 21 | [32855] = Format.R5G5B5A1UNormPack16, 22 | [32856] = Format.R8G8B8A8UNorm 23 | }; 24 | 25 | public static VulkanImage LoadKtxVulkanImage(IVulkanAppHost host, VulkanContext ctx, string path) 26 | { 27 | using (var reader = new BinaryReader(host.Open(path))) 28 | { 29 | byte[] identifier = reader.ReadBytes(12); 30 | 31 | if (!identifier.SequenceEqual(KtxIdentifier)) 32 | throw new InvalidOperationException("File is not in Khronos Texture format."); 33 | 34 | int endienness = reader.ReadInt32(); 35 | int glType = reader.ReadInt32(); 36 | int glTypeSize = reader.ReadInt32(); 37 | int glFormat = reader.ReadInt32(); 38 | int glInternalFormat = reader.ReadInt32(); 39 | int glBaseInternalFormat = reader.ReadInt32(); 40 | int pixelWidth = reader.ReadInt32(); 41 | int pixelHeight = reader.ReadInt32(); 42 | int pixelDepth = reader.ReadInt32(); 43 | int numberOfArrayElements = reader.ReadInt32(); 44 | int numberOfFaces = reader.ReadInt32(); 45 | int numberOfMipmapLevels = reader.ReadInt32(); 46 | int bytesOfKeyValueData = reader.ReadInt32(); 47 | 48 | // Skip key-value data. 49 | reader.ReadBytes(bytesOfKeyValueData); 50 | 51 | // Some of the values may be 0 - ensure at least 1. 52 | pixelWidth = Math.Max(pixelWidth, 1); 53 | pixelHeight = Math.Max(pixelHeight, 1); 54 | pixelDepth = Math.Max(pixelDepth, 1); 55 | numberOfArrayElements = Math.Max(numberOfArrayElements, 1); 56 | numberOfFaces = Math.Max(numberOfFaces, 1); 57 | numberOfMipmapLevels = Math.Max(numberOfMipmapLevels, 1); 58 | 59 | int numberOfSlices = Math.Max(numberOfFaces, numberOfArrayElements); 60 | 61 | if (!_glInternalFormatToVkFormat.TryGetValue(glInternalFormat, out Format format)) 62 | throw new NotImplementedException("glInternalFormat not mapped to VkFormat."); 63 | 64 | var data = new TextureData 65 | { 66 | Mipmaps = new TextureData.Mipmap[numberOfMipmapLevels], 67 | Format = format 68 | }; 69 | 70 | for (int i = 0; i < numberOfMipmapLevels; i++) 71 | { 72 | var mipmap = new TextureData.Mipmap 73 | { 74 | Size = reader.ReadInt32(), 75 | Extent = new Extent3D(pixelWidth, pixelHeight, pixelDepth) 76 | }; 77 | mipmap.Data = reader.ReadBytes(mipmap.Size); 78 | data.Mipmaps[i] = mipmap; 79 | break; // TODO: impl 80 | //for (int j = 0; j < numberOfArrayElements; j++) 81 | //{ 82 | // for (int k = 0; k < numberOfFaces; k++) 83 | // { 84 | // for (int l = 0; l < pixelDepth; l++) 85 | // { 86 | // //for (int row = 0; 87 | // // row < ) 88 | // } 89 | // } 90 | //} 91 | } 92 | 93 | return VulkanImage.Texture2D(ctx, data); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Samples/MiniFramework/ContentLoaders/ShaderModule.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace VulkanCore.Samples.ContentLoaders 4 | { 5 | internal static partial class Loader 6 | { 7 | public static ShaderModule LoadShaderModule(IVulkanAppHost host, VulkanContext ctx, string path) 8 | { 9 | const int defaultBufferSize = 4096; 10 | using (Stream stream = host.Open(path)) 11 | using (var ms = new MemoryStream()) 12 | { 13 | stream.CopyTo(ms, defaultBufferSize); 14 | return ctx.Device.CreateShaderModule(new ShaderModuleCreateInfo(ms.ToArray())); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Samples/MiniFramework/ContentManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using static VulkanCore.Samples.ContentLoaders.Loader; 5 | 6 | namespace VulkanCore.Samples 7 | { 8 | public class ContentManager : IDisposable 9 | { 10 | private readonly IVulkanAppHost _host; 11 | private readonly VulkanContext _ctx; 12 | private readonly string _contentRoot; 13 | private readonly Dictionary _cachedContent = new Dictionary(); 14 | 15 | public ContentManager(IVulkanAppHost host, VulkanContext ctx, string contentRoot) 16 | { 17 | _host = host; 18 | _ctx = ctx; 19 | _contentRoot = contentRoot; 20 | } 21 | 22 | public T Load(string contentName) 23 | { 24 | if (_cachedContent.TryGetValue(contentName, out IDisposable value)) 25 | return (T)value; 26 | 27 | string path = Path.Combine(_contentRoot, contentName); 28 | string extension = Path.GetExtension(path); 29 | 30 | Type type = typeof(T); 31 | if (type == typeof(ShaderModule)) 32 | { 33 | value = LoadShaderModule(_host, _ctx, path); 34 | } 35 | else if (type == typeof(VulkanImage)) 36 | { 37 | if (extension.Equals(".ktx", StringComparison.OrdinalIgnoreCase)) 38 | { 39 | value = LoadKtxVulkanImage(_host, _ctx, path); 40 | } 41 | } 42 | 43 | if (value == null) 44 | throw new NotImplementedException("Content type or extension not implemented."); 45 | 46 | _cachedContent.Add(contentName, value); 47 | return (T)value; 48 | } 49 | 50 | public void Dispose() 51 | { 52 | foreach (IDisposable value in _cachedContent.Values) 53 | value.Dispose(); 54 | _cachedContent.Clear(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Samples/MiniFramework/GeometricPrimitive.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Samples 5 | { 6 | [StructLayout(LayoutKind.Sequential)] 7 | public struct Vertex 8 | { 9 | public Vector3 Position; 10 | public Vector3 Normal; 11 | public Vector2 TexCoord; 12 | 13 | public Vertex(Vector3 p, Vector3 n, Vector2 uv) 14 | { 15 | Position = p; 16 | Normal = n; 17 | TexCoord = uv; 18 | } 19 | 20 | public Vertex( 21 | float px, float py, float pz, 22 | float nx, float ny, float nz, 23 | float u, float v) 24 | { 25 | Position = new Vector3(px, py, pz); 26 | Normal = new Vector3(nx, ny, nz); 27 | TexCoord = new Vector2(u, v); 28 | } 29 | } 30 | 31 | public class GeometricPrimitive 32 | { 33 | public Vertex[] Vertices { get; } 34 | public int[] Indices { get; } 35 | 36 | public GeometricPrimitive(Vertex[] vertices, int[] indices) 37 | { 38 | Vertices = vertices; 39 | Indices = indices; 40 | } 41 | 42 | public static GeometricPrimitive Box(float width, float height, float depth) 43 | { 44 | float w2 = 0.5f * width; 45 | float h2 = 0.5f * height; 46 | float d2 = 0.5f * depth; 47 | 48 | Vertex[] vertices = 49 | { 50 | // Fill in the front face vertex data. 51 | new Vertex(-w2, +h2, -d2, +0, +0, -1, +0, +0), 52 | new Vertex(-w2, -h2, -d2, +0, +0, -1, +0, +1), 53 | new Vertex(+w2, -h2, -d2, +0, +0, -1, +1, +1), 54 | new Vertex(+w2, +h2, -d2, +0, +0, -1, +1, +0), 55 | // Fill in the back face vertex data. 56 | new Vertex(-w2, +h2, +d2, +0, +0, +1, +1, +0), 57 | new Vertex(+w2, +h2, +d2, +0, +0, +1, +0, +0), 58 | new Vertex(+w2, -h2, +d2, +0, +0, +1, +0, +1), 59 | new Vertex(-w2, -h2, +d2, +0, +0, +1, +1, +1), 60 | // Fill in the top face vertex data. 61 | new Vertex(-w2, -h2, -d2, +0, +1, +0, +0, +0), 62 | new Vertex(-w2, -h2, +d2, +0, +1, +0, +0, +1), 63 | new Vertex(+w2, -h2, +d2, +0, +1, +0, +1, +1), 64 | new Vertex(+w2, -h2, -d2, +0, +1, +0, +1, +0), 65 | // Fill in the bottom face vertex data. 66 | new Vertex(-w2, +h2, -d2, +0, -1, +0, +1, +0), 67 | new Vertex(+w2, +h2, -d2, +0, -1, +0, +0, +0), 68 | new Vertex(+w2, +h2, +d2, +0, -1, +0, +0, +1), 69 | new Vertex(-w2, +h2, +d2, +0, -1, +0, +1, +1), 70 | // Fill in the left face vertex data. 71 | new Vertex(-w2, +h2, +d2, -1, +0, +0, +0, +0), 72 | new Vertex(-w2, -h2, +d2, -1, +0, +0, +0, +1), 73 | new Vertex(-w2, -h2, -d2, -1, +0, +0, +1, +1), 74 | new Vertex(-w2, +h2, -d2, -1, +0, +0, +1, +0), 75 | // Fill in the right face vertex data. 76 | new Vertex(+w2, +h2, -d2, +1, +0, +0, +0, +0), 77 | new Vertex(+w2, -h2, -d2, +1, +0, +0, +0, +1), 78 | new Vertex(+w2, -h2, +d2, +1, +0, +0, +1, +1), 79 | new Vertex(+w2, +h2, +d2, +1, +0, +0, +1, +0) 80 | }; 81 | 82 | int[] indices = 83 | { 84 | // Fill in the front face index data. 85 | 0, 1, 2, 0, 2, 3, 86 | // Fill in the back face index data. 87 | 4, 5, 6, 4, 6, 7, 88 | // Fill in the top face index data. 89 | 8, 9, 10, 8, 10, 11, 90 | // Fill in the bottom face index data. 91 | 12, 13, 14, 12, 14, 15, 92 | // Fill in the left face index data 93 | 16, 17, 18, 16, 18, 19, 94 | // Fill in the right face index data 95 | 20, 21, 22, 20, 22, 23 96 | }; 97 | 98 | return new GeometricPrimitive(vertices, indices); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Samples/MiniFramework/MiniFramework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.3 5 | MiniFramework 6 | VulkanCore.Samples 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Samples/MiniFramework/Timer.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace VulkanCore.Samples 4 | { 5 | public class Timer 6 | { 7 | private readonly double _secondsPerCount; 8 | private double _deltaTime; 9 | 10 | private long _baseTime; 11 | private long _pausedTime; 12 | private long _stopTime; 13 | private long _prevTime; 14 | private long _currTime; 15 | 16 | private bool _stopped; 17 | 18 | public Timer() 19 | { 20 | Debug.Assert(Stopwatch.IsHighResolution, 21 | "System does not support high-resolution performance counter."); 22 | 23 | _secondsPerCount = 0.0; 24 | _deltaTime = -1.0; 25 | _baseTime = 0; 26 | _pausedTime = 0; 27 | _prevTime = 0; 28 | _currTime = 0; 29 | _stopped = false; 30 | 31 | long countsPerSec = Stopwatch.Frequency; 32 | _secondsPerCount = 1.0 / countsPerSec; 33 | } 34 | 35 | public float TotalTime 36 | { 37 | get 38 | { 39 | if (_stopped) 40 | return (float)((_stopTime - _pausedTime - _baseTime) * _secondsPerCount); 41 | 42 | return (float)((_currTime - _pausedTime - _baseTime) * _secondsPerCount); 43 | } 44 | } 45 | 46 | public float DeltaTime => (float)_deltaTime; 47 | 48 | public void Reset() 49 | { 50 | long curTime = Stopwatch.GetTimestamp(); 51 | _baseTime = curTime; 52 | _prevTime = curTime; 53 | _stopTime = 0; 54 | _stopped = false; 55 | } 56 | 57 | public void Start() 58 | { 59 | long startTime = Stopwatch.GetTimestamp(); 60 | if (_stopped) 61 | { 62 | _pausedTime += (startTime - _stopTime); 63 | _prevTime = startTime; 64 | _stopTime = 0; 65 | _stopped = false; 66 | } 67 | } 68 | 69 | public void Stop() 70 | { 71 | if (!_stopped) 72 | { 73 | long curTime = Stopwatch.GetTimestamp(); 74 | _stopTime = curTime; 75 | _stopped = true; 76 | } 77 | } 78 | 79 | public void Tick() 80 | { 81 | if (_stopped) 82 | { 83 | _deltaTime = 0.0; 84 | return; 85 | } 86 | 87 | long curTime = Stopwatch.GetTimestamp(); 88 | _currTime = curTime; 89 | _deltaTime = (_currTime - _prevTime) * _secondsPerCount; 90 | 91 | _prevTime = _currTime; 92 | if (_deltaTime < 0.0) 93 | _deltaTime = 0.0; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Samples/Shared/01-ClearScreen/ClearScreenApp.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Khr; 2 | 3 | namespace VulkanCore.Samples.ClearScreen 4 | { 5 | public class ClearScreenApp : VulkanApp 6 | { 7 | protected override void RecordCommandBuffer(CommandBuffer cmdBuffer, int imageIndex) 8 | { 9 | var imageSubresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1); 10 | 11 | var barrierFromPresentToClear = new ImageMemoryBarrier( 12 | SwapchainImages[imageIndex], imageSubresourceRange, 13 | Accesses.None, Accesses.TransferWrite, 14 | ImageLayout.Undefined, ImageLayout.TransferDstOptimal); 15 | var barrierFromClearToPresent = new ImageMemoryBarrier( 16 | SwapchainImages[imageIndex], imageSubresourceRange, 17 | Accesses.TransferWrite, Accesses.MemoryRead, 18 | ImageLayout.TransferDstOptimal, ImageLayout.PresentSrcKhr); 19 | 20 | cmdBuffer.CmdPipelineBarrier( 21 | PipelineStages.Transfer, PipelineStages.Transfer, 22 | imageMemoryBarriers: new[] { barrierFromPresentToClear }); 23 | cmdBuffer.CmdClearColorImage( 24 | SwapchainImages[imageIndex], 25 | ImageLayout.TransferDstOptimal, 26 | new ClearColorValue(new ColorF4(0.39f, 0.58f, 0.93f, 1.0f)), 27 | imageSubresourceRange); 28 | cmdBuffer.CmdPipelineBarrier( 29 | PipelineStages.Transfer, PipelineStages.Transfer, 30 | imageMemoryBarriers: new[] { barrierFromClearToPresent }); 31 | } 32 | 33 | protected override void Draw(Timer timer) 34 | { 35 | // Acquire an index of drawing image for this frame. 36 | int imageIndex = Swapchain.AcquireNextImage(semaphore: ImageAvailableSemaphore); 37 | 38 | // Use a fence to wait until the command buffer has finished execution before using it again 39 | SubmitFences[imageIndex].Wait(); 40 | SubmitFences[imageIndex].Reset(); 41 | 42 | // Submit recorded commands to graphics queue for execution. 43 | Context.GraphicsQueue.Submit( 44 | ImageAvailableSemaphore, 45 | PipelineStages.Transfer, 46 | CommandBuffers[imageIndex], 47 | RenderingFinishedSemaphore, 48 | SubmitFences[imageIndex] 49 | ); 50 | 51 | // Present the color output to screen. 52 | Context.PresentQueue.PresentKhr(RenderingFinishedSemaphore, Swapchain, imageIndex); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Samples/Shared/02-ColoredTriangle/Content/CompileShaders.bat: -------------------------------------------------------------------------------- 1 | REM Make the directory batch file resides in as the working directory. 2 | pushd %~dp0 3 | 4 | glslangvalidator -V Shader.vert -o Shader.vert.spv 5 | glslangvalidator -V Shader.frag -o Shader.frag.spv 6 | 7 | popd 8 | -------------------------------------------------------------------------------- /Samples/Shared/02-ColoredTriangle/Content/Shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (location = 0) in vec3 in_Color; 4 | 5 | layout(location = 0) out vec4 out_Color; 6 | 7 | void main() { 8 | out_Color = vec4(in_Color, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /Samples/Shared/02-ColoredTriangle/Content/Shader.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/02-ColoredTriangle/Content/Shader.frag.spv -------------------------------------------------------------------------------- /Samples/Shared/02-ColoredTriangle/Content/Shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (location = 0) out vec3 out_Color; 4 | 5 | out gl_PerVertex 6 | { 7 | vec4 gl_Position; 8 | }; 9 | 10 | void main() { 11 | vec2 pos[3] = vec2[3](vec2(-0.7, 0.7), vec2(0.7, 0.7), vec2(0.0, -0.7)); 12 | vec3 color[3] = vec3[3](vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0)); 13 | 14 | out_Color = color[gl_VertexIndex]; 15 | gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /Samples/Shared/02-ColoredTriangle/Content/Shader.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/02-ColoredTriangle/Content/Shader.vert.spv -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/CompileShaders.bat: -------------------------------------------------------------------------------- 1 | REM Make the directory batch file resides in as the working directory. 2 | pushd %~dp0 3 | 4 | glslangvalidator -V Shader.vert -o Shader.vert.spv 5 | glslangvalidator -V Shader.frag -o Shader.frag.spv 6 | 7 | popd 8 | -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/IndustryForgedDark512.ktx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/03-TexturedCube/Content/IndustryForgedDark512.ktx -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/Shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (binding = 1) uniform sampler2D sampler_Color; 4 | 5 | layout (location = 0) in vec2 in_TexCoord; 6 | 7 | layout (location = 0) out vec4 out_Color; 8 | 9 | void main() { 10 | vec4 color = texture(sampler_Color, in_TexCoord); 11 | 12 | out_Color = vec4(color.rgb, 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/Shader.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/03-TexturedCube/Content/Shader.frag.spv -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/Shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (location = 0) in vec3 in_Position; 4 | layout (location = 1) in vec3 in_Normal; 5 | layout (location = 2) in vec2 in_TexCoord; 6 | 7 | layout (binding = 0) uniform PerFrame 8 | { 9 | mat4 World; 10 | mat4 View; 11 | mat4 Projection; 12 | }; 13 | 14 | layout (location = 0) out vec2 out_TexCoord; 15 | 16 | out gl_PerVertex 17 | { 18 | vec4 gl_Position; 19 | }; 20 | 21 | void main() { 22 | out_TexCoord = in_TexCoord; 23 | gl_Position = Projection * View * World * vec4(in_Position.xyz, 1.0); 24 | } 25 | -------------------------------------------------------------------------------- /Samples/Shared/03-TexturedCube/Content/Shader.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/03-TexturedCube/Content/Shader.vert.spv -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/CompileShaders.bat: -------------------------------------------------------------------------------- 1 | REM Make the directory batch file resides in as the working directory. 2 | pushd %~dp0 3 | 4 | glslangvalidator -V Shader.vert -o Shader.vert.spv 5 | glslangvalidator -V Shader.frag -o Shader.frag.spv 6 | glslangvalidator -V Shader.comp -o Shader.comp.spv 7 | 8 | popd 9 | -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/ParticleDiffuse.ktx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/04-ComputeParticles/Content/ParticleDiffuse.ktx -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (local_size_x = 256) in; 4 | 5 | struct VertexParticle 6 | { 7 | vec2 Position; 8 | vec2 Velocity; 9 | vec4 Color; 10 | }; 11 | 12 | layout(std140, binding = 0) buffer layout_Particles 13 | { 14 | VertexParticle Particles[]; 15 | }; 16 | 17 | layout (binding = 1) uniform layout_Global 18 | { 19 | vec2 DstPosition; 20 | float DeltaTime; 21 | float Padding; 22 | }; 23 | 24 | void main() 25 | { 26 | uint index = gl_GlobalInvocationID.x; 27 | vec2 position = Particles[index].Position; 28 | vec2 velocity = Particles[index].Velocity; 29 | vec4 color = Particles[index].Color; 30 | 31 | // Adjust velocity towards destination. 32 | vec2 deltaPosition = DstPosition - position; 33 | float distanceSquared = dot(deltaPosition, deltaPosition); 34 | velocity += deltaPosition * (1.0 / (distanceSquared)) * -0.0005; 35 | 36 | // Move position by velocity. 37 | position += velocity * DeltaTime; 38 | 39 | // Collide from window edges. 40 | if (position.x < -1 || position.x > 1 || position.y < -1 || position.y > 1) 41 | { 42 | velocity = -velocity; 43 | position = clamp(position, vec2(-1, -1), vec2(1, 1)); 44 | } 45 | 46 | Particles[index] = VertexParticle(position, velocity, color); 47 | } 48 | -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.comp.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/04-ComputeParticles/Content/Shader.comp.spv -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (binding = 0) uniform sampler2D sampler_Diffuse; 4 | 5 | layout (location = 0) in vec4 in_Color; 6 | 7 | layout (location = 0) out vec4 out_Color; 8 | 9 | void main() 10 | { 11 | out_Color.rgb = texture(sampler_Diffuse, gl_PointCoord).rgb * in_Color.rgb; 12 | } 13 | -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/04-ComputeParticles/Content/Shader.frag.spv -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (location = 0) in vec2 in_Position; 4 | layout (location = 1) in vec2 in_Velocity; 5 | layout (location = 2) in vec4 in_Color; 6 | 7 | layout (location = 0) out vec4 out_Color; 8 | 9 | out gl_PerVertex 10 | { 11 | vec4 gl_Position; 12 | float gl_PointSize; 13 | }; 14 | 15 | void main () 16 | { 17 | gl_Position = vec4(in_Position, 1.0, 1.0); 18 | gl_PointSize = 4.0; 19 | out_Color = in_Color; 20 | } 21 | -------------------------------------------------------------------------------- /Samples/Shared/04-ComputeParticles/Content/Shader.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/04-ComputeParticles/Content/Shader.vert.spv -------------------------------------------------------------------------------- /Samples/Shared/MacOSWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Threading; 5 | 6 | namespace VulkanCore.Samples 7 | { 8 | public class MacOSWindow : IVulkanAppHost 9 | { 10 | private readonly string _title; 11 | private readonly Timer _timer = new Timer(); 12 | private readonly VulkanApp _app; 13 | 14 | private NativeMacOS.NativeApp _nativeApp; 15 | private NativeMacOS.NativeWindow _nativeWindow; 16 | private NativeMacOS.NativeMetalView _nativeMetalView; 17 | 18 | private bool _appPaused; 19 | private bool _running; 20 | 21 | private int _frameCount; 22 | private float _timeElapsed; 23 | 24 | public MacOSWindow(string title, VulkanApp app) 25 | { 26 | _title = title; 27 | _app = app; 28 | } 29 | 30 | public IntPtr WindowHandle => _nativeMetalView.NativeMetalViewPointer; 31 | public IntPtr InstanceHandle => Process.GetCurrentProcess().Handle; 32 | public int Width { get; private set; } = 1280; 33 | public int Height { get; private set; } = 720; 34 | public Platform Platform => Platform.MacOS; 35 | 36 | public Stream Open(string path) => new FileStream(Path.Combine("bin", path), FileMode.Open, FileAccess.Read); 37 | 38 | public void Initialize() 39 | { 40 | _nativeApp = new NativeMacOS.NativeApp(); 41 | _nativeWindow = new NativeMacOS.NativeWindow(_nativeApp, new NativeMacOS.Size(Width, Height)); 42 | _nativeWindow.MinSize = new NativeMacOS.Size(200f, 200f); 43 | _nativeWindow.Title = _title; 44 | _nativeWindow.BeginResizing += () => 45 | { 46 | _appPaused = true; 47 | _timer.Stop(); 48 | }; 49 | _nativeWindow.EndResizing += () => 50 | { 51 | _appPaused = false; 52 | _timer.Start(); 53 | _app.Resize(); 54 | }; 55 | _nativeWindow.Resized += size => 56 | { 57 | Width = (int)size.Width; 58 | Height = (int)size.Height; 59 | }; 60 | _nativeWindow.CloseRequested += () => 61 | { 62 | _running = false; 63 | }; 64 | _nativeMetalView = new NativeMacOS.NativeMetalView(_nativeWindow); 65 | 66 | _app.Initialize(this); 67 | _running = true; 68 | _timer.Start(); 69 | } 70 | 71 | public void Run() 72 | { 73 | _running = true; 74 | _timer.Reset(); 75 | while (_running) 76 | { 77 | _nativeApp.ProcessEvents(); 78 | _timer.Tick(); 79 | if (!_appPaused) 80 | { 81 | CalculateFrameRateStats(); 82 | _app.Tick(_timer); 83 | } 84 | else 85 | { 86 | Thread.Sleep(100); 87 | } 88 | } 89 | } 90 | 91 | public void Dispose() 92 | { 93 | _app.Dispose(); 94 | _nativeWindow.Dispose(); 95 | _nativeApp.Dispose(); 96 | } 97 | 98 | private void CalculateFrameRateStats() 99 | { 100 | _frameCount++; 101 | 102 | if (_timer.TotalTime - _timeElapsed >= 1.0f) 103 | { 104 | float fps = _frameCount; 105 | float mspf = 1000.0f / fps; 106 | 107 | _nativeWindow.Title = $"{_title} Fps: {fps} Mspf: {mspf}"; 108 | 109 | // Reset for next average. 110 | _frameCount = 0; 111 | _timeElapsed += 1.0f; 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Samples/Shared/NativeMacOS/NativeMacOS.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/NativeMacOS/NativeMacOS.dll -------------------------------------------------------------------------------- /Samples/Shared/NativeMacOS/libmacwindow.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/NativeMacOS/libmacwindow.dylib -------------------------------------------------------------------------------- /Samples/Shared/System.Numerics.Vectors.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Samples/Shared/System.Numerics.Vectors.dll -------------------------------------------------------------------------------- /Samples/Shared/VulkanSurfaceView.cs: -------------------------------------------------------------------------------- 1 | using Android.Content; 2 | using Android.Runtime; 3 | using Android.Views; 4 | using System; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | using System.Threading; 8 | using AndroidApplication = Android.App.Application; 9 | using AndroidFormat = Android.Graphics.Format; 10 | 11 | namespace VulkanCore.Samples 12 | { 13 | public class VulkanSurfaceView : SurfaceView, ISurfaceHolderCallback, IVulkanAppHost 14 | { 15 | // Threading timer for render loop. 16 | private static readonly int _renderDueTime = (int)Math.Ceiling(1000.0f / 60.0f); 17 | private System.Threading.Timer _tickTimer; 18 | private bool _appPaused; 19 | 20 | // Game timer used by samples for elapsed/total duration. 21 | private readonly Timer _gameTimer = new Timer(); 22 | 23 | private VulkanApp _app; 24 | 25 | public VulkanSurfaceView(Context ctx, VulkanApp app) : base(ctx) 26 | { 27 | Initialize(app); 28 | } 29 | 30 | public IntPtr WindowHandle { get; private set; } 31 | public IntPtr InstanceHandle => Handle; 32 | public Platform Platform => Platform.Android; 33 | 34 | public Stream Open(string path) => Context.Assets.Open(path); 35 | 36 | private void Initialize(VulkanApp app) 37 | { 38 | _app = app; 39 | Holder.AddCallback(this); 40 | } 41 | 42 | private void Tick() 43 | { 44 | _gameTimer.Tick(); 45 | _app.Tick(_gameTimer); 46 | } 47 | 48 | #region ISurfaceHolderCallback implementation 49 | 50 | public void SurfaceCreated(ISurfaceHolder holder) 51 | { 52 | WindowHandle = ANativeWindow_fromSurface(JNIEnv.Handle, holder.Surface.Handle); 53 | 54 | _appPaused = false; 55 | _app.Initialize(this); 56 | 57 | _gameTimer.Start(); 58 | _tickTimer = new System.Threading.Timer(state => 59 | { 60 | AndroidApplication.SynchronizationContext.Send(_ => { if (!_appPaused) Tick(); }, state); 61 | _tickTimer.Change(_renderDueTime, Timeout.Infinite); 62 | }, null, _renderDueTime, Timeout.Infinite); 63 | } 64 | 65 | public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] AndroidFormat format, int width, int height) 66 | { 67 | _app.Resize(); 68 | } 69 | 70 | public void SurfaceDestroyed(ISurfaceHolder holder) 71 | { 72 | _gameTimer.Stop(); 73 | _tickTimer.Change(Timeout.Infinite, Timeout.Infinite); 74 | _tickTimer.Dispose(); 75 | _app.Dispose(); 76 | ANativeWindow_release(WindowHandle); 77 | _appPaused = true; 78 | } 79 | 80 | #endregion 81 | 82 | [DllImport("android")] 83 | private static extern IntPtr ANativeWindow_fromSurface(IntPtr jni, IntPtr surface); 84 | 85 | [DllImport("android")] 86 | private static extern void ANativeWindow_release(IntPtr surface); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Samples/Win32/01-ClearScreen/01-ClearScreen.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Triangle.Win32 5 | WinExe 6 | true 7 | ClearScreen 8 | net461;net5.0-windows 9 | VulkanCore.Samples.ClearScreen 10 | VulkanCore.Samples.ClearScreen.Program 11 | 12 | 13 | 14 | 15 | {1772437f-982d-4edf-80e8-11b826219041} 16 | VulkanCore 17 | 18 | 19 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 20 | MiniFramework 21 | 22 | 23 | 24 | 25 | 26 | ClearScreenApp.cs 27 | 28 | 29 | Win32Window.cs 30 | 31 | 32 | 33 | 34 | 35 | 4.5.1 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Samples/Win32/01-ClearScreen/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ClearScreen 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new Win32Window( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ClearScreenApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/Win32/02-ColoredTriangle/02-ColoredTriangle.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 02-Triangle 5 | WinExe 6 | true 7 | ColoredTriangle 8 | net461;net5.0-windows 9 | VulkanCore.Samples.ColoredTriangle 10 | VulkanCore.Samples.ColoredTriangle.Program 11 | 12 | 13 | 14 | 15 | {1772437f-982d-4edf-80e8-11b826219041} 16 | VulkanCore 17 | 18 | 19 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 20 | MiniFramework 21 | 22 | 23 | 24 | 25 | 26 | ColoredTriangleApp.cs 27 | 28 | 29 | Win32Window.cs 30 | 31 | 32 | Content\CompileShaders.bat 33 | 34 | 35 | Content\Shader.frag 36 | 37 | 38 | Content\Shader.frag.spv 39 | PreserveNewest 40 | 41 | 42 | Content\Shader.vert 43 | 44 | 45 | Content\Shader.vert.spv 46 | PreserveNewest 47 | 48 | 49 | 50 | 51 | 52 | 4.5.1 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Samples/Win32/02-ColoredTriangle/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ColoredTriangle 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new Win32Window( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ColoredTriangleApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/Win32/03-TexturedCube/03-TexturedCube.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 03-Cube 5 | WinExe 6 | true 7 | TexturedCube 8 | net461;net5.0-windows 9 | VulkanCore.Samples.TexturedCube 10 | VulkanCore.Samples.TexturedCube.Program 11 | 12 | 13 | 14 | 15 | {1772437f-982d-4edf-80e8-11b826219041} 16 | VulkanCore 17 | 18 | 19 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 20 | MiniFramework 21 | 22 | 23 | 24 | 25 | 26 | TexturedCubeApp.cs 27 | 28 | 29 | Win32Window.cs 30 | 31 | 32 | 33 | 34 | 35 | Content\CompileShaders.bat 36 | 37 | 38 | Content\Shader.frag 39 | 40 | 41 | Content\Shader.frag.spv 42 | PreserveNewest 43 | 44 | 45 | Content\Shader.vert 46 | 47 | 48 | Content\Shader.vert.spv 49 | PreserveNewest 50 | 51 | 52 | Content\IndustryForgedDark512.ktx 53 | PreserveNewest 54 | 55 | 56 | 57 | 58 | 59 | 4.5.1 60 | 61 | 62 | 4.5.0 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Samples/Win32/03-TexturedCube/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.TexturedCube 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new Win32Window( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new TexturedCubeApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/Win32/04-ComputeParticles/04-ComputeParticles.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 04-ComputeParticles 5 | WinExe 6 | true 7 | ComputeParticles 8 | net461;net5.0-windows 9 | VulkanCore.Samples.ComputeParticles 10 | VulkanCore.Samples.ComputeParticles.Program 11 | 12 | 13 | 14 | 15 | {1772437f-982d-4edf-80e8-11b826219041} 16 | VulkanCore 17 | 18 | 19 | {9becf614-4e1a-4053-a7a0-3a7b0bca0cf0} 20 | MiniFramework 21 | 22 | 23 | 24 | 25 | 26 | ComputeParticlesApp.cs 27 | 28 | 29 | Win32Window.cs 30 | 31 | 32 | 33 | 34 | 35 | Content\CompileShaders.bat 36 | 37 | 38 | Content\Shader.comp 39 | 40 | 41 | Content\Shader.comp.spv 42 | PreserveNewest 43 | 44 | 45 | Content\Shader.frag 46 | 47 | 48 | Content\Shader.frag.spv 49 | PreserveNewest 50 | 51 | 52 | Content\Shader.vert 53 | 54 | 55 | Content\Shader.vert.spv 56 | PreserveNewest 57 | 58 | 59 | Content\ParticleDiffuse.ktx 60 | PreserveNewest 61 | 62 | 63 | 64 | 65 | 66 | 4.5.1 67 | 68 | 69 | 4.5.0 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Samples/Win32/04-ComputeParticles/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace VulkanCore.Samples.ComputeParticles 5 | { 6 | public static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | public static void Main() 13 | { 14 | using (var window = new Win32Window( 15 | Assembly.GetExecutingAssembly().GetName().Name, 16 | new ComputeParticlesApp())) 17 | { 18 | window.Initialize(); 19 | window.Run(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Src/Android/DeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Android 5 | { 6 | /// 7 | /// Provides Android specific extension methods for the class. 8 | /// 9 | public static unsafe class DeviceExtensions 10 | { 11 | /// Vulkan returns an error code. 12 | public static int GetSwapchainGrallocUsageAndroid(this Device device, Format format, int imageUsage) 13 | { 14 | int usage; 15 | Result result = vkGetSwapchainGrallocUsageANDROID(device)(device, format, imageUsage, &usage); 16 | VulkanException.ThrowForInvalidResult(result); 17 | return usage; 18 | } 19 | 20 | private delegate Result vkGetSwapchainGrallocUsageANDROIDDelegate(IntPtr device, Format format, int imageUsage, int* grallocUsage); 21 | private static vkGetSwapchainGrallocUsageANDROIDDelegate vkGetSwapchainGrallocUsageANDROID(Device device) => device.GetProc(nameof(vkGetSwapchainGrallocUsageANDROID)); 22 | } 23 | 24 | [StructLayout(LayoutKind.Sequential)] 25 | public struct NativeBufferAndroid 26 | { 27 | public StructureType Type; 28 | public IntPtr Next; 29 | public IntPtr Handle; 30 | public int Stride; 31 | public int Format; 32 | public int Usage; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Src/Android/ImageExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Android 4 | { 5 | /// 6 | /// Provides Android specific extension methods for the class. 7 | /// 8 | public static unsafe class ImageExtensions 9 | { 10 | /// Vulkan returns an error code. 11 | public static void AcquireAndroid(this Queue queue, 12 | Image image, int nativeFenceFd, Semaphore semaphore, Fence fence) 13 | { 14 | Result result = vkAcquireImageANDROID(queue)(queue, image, nativeFenceFd, semaphore, fence); 15 | VulkanException.ThrowForInvalidResult(result); 16 | } 17 | 18 | private delegate Result vkAcquireImageANDROIDDelegate(IntPtr device, long image, int nativeFenceFd, long semaphore, long fence); 19 | private static vkAcquireImageANDROIDDelegate vkAcquireImageANDROID(Queue queue) => queue.Parent.GetProc(nameof(vkAcquireImageANDROID)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Src/Android/QueueExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Android 4 | { 5 | /// 6 | /// Provides Android specific extension methods for the class. 7 | /// 8 | public static unsafe class QueueExtensions 9 | { 10 | /// Vulkan returns an error code. 11 | public static int SignalReleaseImageAndroid(this Queue queue, Semaphore[] waitSemaphores, Image image) 12 | { 13 | int count = waitSemaphores?.Length ?? 0; 14 | var semaphoreHandles = stackalloc long[count]; 15 | for (int i = 0; i < count; i++) 16 | semaphoreHandles[i] = waitSemaphores[i]; 17 | 18 | int nativeFenceFd; 19 | Result result = vkQueueSignalReleaseImageANDROID(queue)(queue, count, semaphoreHandles, image, &nativeFenceFd); 20 | VulkanException.ThrowForInvalidResult(result); 21 | return nativeFenceFd; 22 | } 23 | 24 | private delegate Result vkQueueSignalReleaseImageANDROIDDelegate(IntPtr queue, int waitSemaphoreCount, long* waitSemaphores, long image, int* nativeFenceFd); 25 | private static vkQueueSignalReleaseImageANDROIDDelegate vkQueueSignalReleaseImageANDROID(Queue queue) => queue.Parent.GetProc(nameof(vkQueueSignalReleaseImageANDROID)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Src/Bool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore 5 | { 6 | /// 7 | /// Vulkan boolean type. 8 | /// 9 | /// true represents a boolean True (integer 1) value, and false a boolean False 10 | /// (integer 0) value. 11 | /// 12 | /// 13 | [StructLayout(LayoutKind.Sequential)] 14 | public struct Bool : IEquatable 15 | { 16 | private readonly int _value; 17 | 18 | /// 19 | /// Initializes a new instance of the struct. 20 | /// 21 | /// 22 | public Bool(bool value) 23 | { 24 | _value = value ? Constant.True : Constant.False; 25 | } 26 | 27 | /// 28 | /// Returns a string representing this instance. 29 | /// 30 | /// The string representation. 31 | public override string ToString() => ((bool)this).ToString(); 32 | 33 | /// 34 | /// Returns a boolean indicating whether the given is equal to this instance. 36 | /// 37 | /// The to compare this instance to. 38 | /// 39 | /// true if the other is equal to this instance; false otherwise. 40 | /// 41 | public bool Equals(Bool other) => _value == other._value; 42 | 43 | /// 44 | /// Returns a boolean indicating whether the given is equal to this instance. 46 | /// 47 | /// The to compare against. 48 | /// 49 | /// true if the is equal to this instance; false otherwise. 50 | /// 51 | public override bool Equals(object obj) => obj is Bool && Equals((Bool)obj); 52 | 53 | /// 54 | /// Returns the hash code for this instance. 55 | /// 56 | /// The hash code. 57 | public override int GetHashCode() => _value.GetHashCode(); 58 | 59 | /// 60 | /// Returns a boolean indicating whether the two given booleans are equal. 61 | /// 62 | /// The first boolean to compare. 63 | /// The second boolean to compare. 64 | /// true if the booleans are equal; false otherwise. 65 | public static bool operator ==(Bool left, Bool right) => left.Equals(right); 66 | 67 | /// 68 | /// Returns a boolean indicating whether the two given booleans are not equal. 69 | /// 70 | /// The first boolean to compare. 71 | /// The second boolean to compare. 72 | /// 73 | /// true if the booleans are not equal; false if they are equal. 74 | /// 75 | public static bool operator !=(Bool left, Bool right) => !left.Equals(right); 76 | 77 | /// 78 | /// Performs an implicit conversion from to . 79 | /// 80 | /// The value to convert. 81 | public static implicit operator Bool(bool value) => new Bool(value); 82 | 83 | /// 84 | /// Performs an implicit conversion from to . 85 | /// 86 | /// The value to convert. 87 | public static implicit operator bool(Bool value) => value._value == Constant.True; 88 | 89 | /// 90 | /// Performs an implicit conversion from to . 91 | /// 92 | /// The value to convert. 93 | public static implicit operator Bool(int value) => new Bool(value != Constant.False); 94 | 95 | /// 96 | /// Performs an implicit conversion from to . 97 | /// 98 | /// The value to convert. 99 | public static implicit operator int(Bool value) => value._value == Constant.True ? 1 : 0; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Src/Ext/DisplayKhrExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using VulkanCore.Khr; 3 | 4 | namespace VulkanCore.Ext 5 | { 6 | /// 7 | /// Provides extension methods for the class. 8 | /// 9 | public static unsafe class DisplayKhrExtensions 10 | { 11 | /// 12 | /// Acquire access to a DisplayKhr using Xlib. 13 | /// 14 | /// All permissions necessary to control the display are granted to the Vulkan instance 15 | /// associated with until the display is released or the X11 16 | /// connection specified by is terminated. 17 | /// 18 | /// 19 | /// Permission to access the display may be temporarily revoked during periods when the X11 20 | /// server from which control was acquired itself looses access to . 21 | /// 22 | /// 23 | /// During such periods, operations which require access to the display must fail with an 24 | /// approriate error code. 25 | /// 26 | /// 27 | /// If the X11 server associated with does not own , or if permission to access it has already been acquired by another 29 | /// entity, the call must throw with the error code . 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// Vulkan returns an error code. 35 | public static void AcquireXlibDisplayExt(this DisplayKhr display, IntPtr dpy) 36 | { 37 | Result result = vkAcquireXlibDisplayEXT(display)(display.Parent, &dpy, display); 38 | VulkanException.ThrowForInvalidResult(result); 39 | } 40 | 41 | /// 42 | /// Release access to an acquired DisplayKhr. 43 | /// 44 | /// The display to release control of. 45 | /// Vulkan returns an error code. 46 | public static void ReleaseDisplayExt(this DisplayKhr display) 47 | { 48 | Result result = vkReleaseDisplayEXT(display)(display.Parent, display); 49 | VulkanException.ThrowForInvalidResult(result); 50 | } 51 | 52 | private delegate Result vkAcquireXlibDisplayEXTDelegate(IntPtr physicalDevice, IntPtr* dpy, long display); 53 | private static vkAcquireXlibDisplayEXTDelegate vkAcquireXlibDisplayEXT(DisplayKhr display) => GetProc(display, nameof(vkAcquireXlibDisplayEXT)); 54 | 55 | private delegate Result vkReleaseDisplayEXTDelegate(IntPtr physicalDevice, long display); 56 | private static vkReleaseDisplayEXTDelegate vkReleaseDisplayEXT(DisplayKhr display) => GetProc(display, nameof(vkReleaseDisplayEXT)); 57 | 58 | private static TDelegate GetProc(DisplayKhr display, string name) where TDelegate : class => display.Parent.Parent.GetProc(name); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Src/Ext/SamplerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Ext 5 | { 6 | /// 7 | /// Specify reduction mode for texture filtering. 8 | /// 9 | public enum SamplerReductionModeExt 10 | { 11 | /// 12 | /// Indicates that texel values are combined by computing a weighted average of values in the 13 | /// footprint, using weights. 14 | /// 15 | WeightedAverage = 0, 16 | /// 17 | /// Indicates that texel values are combined by taking the component-wise minimum of values 18 | /// in the footprint with non-zero weights. 19 | /// 20 | Min = 1, 21 | /// 22 | /// Indicates that texel values are combined by taking the component-wise maximum of values 23 | /// in the footprint with non-zero weights. 24 | /// 25 | Max = 2 26 | } 27 | 28 | /// 29 | /// Structure describing sampler filter minmax limits that can be supported by an implementation. 30 | /// 31 | [StructLayout(LayoutKind.Sequential)] 32 | public struct PhysicalDeviceSamplerFilterMinmaxPropertiesExt 33 | { 34 | public StructureType Type; 35 | /// 36 | /// Pointer to next structure. 37 | /// 38 | public IntPtr Next; 39 | public Bool FilterMinmaxSingleComponentFormats; 40 | public Bool FilterMinmaxImageComponentMapping; 41 | } 42 | 43 | /// 44 | /// Structure specifying sampler reduction mode. 45 | /// 46 | [StructLayout(LayoutKind.Sequential)] 47 | public struct SamplerReductionModeCreateInfoExt 48 | { 49 | /// 50 | /// The type of this structure. 51 | /// 52 | public StructureType Type; 53 | /// 54 | /// Is or a pointer to an extension-specific structure. 55 | /// 56 | public IntPtr Next; 57 | /// 58 | /// Controls how texture filtering combines texel values. 59 | /// 60 | public SamplerReductionModeExt ReductionMode; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Src/Ext/ShaderModuleExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Ext 5 | { 6 | /// 7 | /// Provides extension methods for the class. 8 | /// 9 | public static class ShaderModuleExtensions 10 | { 11 | /// 12 | /// Specify validation cache to use during shader module creation. 13 | /// 14 | [StructLayout(LayoutKind.Sequential)] 15 | public struct ShaderModuleValidationCacheCreateInfoExt 16 | { 17 | /// 18 | /// The type of this structure. 19 | /// 20 | public StructureType Type; 21 | /// 22 | /// Is or a pointer to an extension-specific structure. 23 | /// 24 | public IntPtr Next; 25 | /// 26 | /// The object from which the results of prior 27 | /// validation attempts will be written, and to which new validation results for this 28 | /// will be written (if not already present). 29 | /// 30 | public long ValidationCache; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Src/Ext/SwapchainKhrExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using VulkanCore.Khr; 3 | 4 | namespace VulkanCore.Ext 5 | { 6 | /// 7 | /// Provides extension methods for the class. 8 | /// 9 | public static unsafe class SwapchainKhrExtensions 10 | { 11 | /// 12 | /// Query the current value of a surface counter. 13 | /// 14 | /// The requested counters become active when the first presentation command for the 15 | /// associated swapchain is processed by the presentation engine. 16 | /// 17 | /// 18 | /// The swapchain from which to query the counter value. 19 | /// The counter to query. 20 | /// The current value of the counter. 21 | /// Vulkan returns an error code. 22 | public static long GetCounterExt(this SwapchainKhr swapchain, SurfaceCountersExt counter) 23 | { 24 | long counterValue; 25 | Result result = vkGetSwapchainCounterEXT(swapchain)(swapchain.Parent, swapchain, counter, &counterValue); 26 | VulkanException.ThrowForInvalidResult(result); 27 | return counterValue; 28 | } 29 | 30 | private delegate Result vkGetSwapchainCounterEXTDelegate(IntPtr device, long swapchain, SurfaceCountersExt counter, long* counterValue); 31 | private static vkGetSwapchainCounterEXTDelegate vkGetSwapchainCounterEXT(SwapchainKhr swapchain) => swapchain.Parent.GetProc(nameof(vkGetSwapchainCounterEXT)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Src/Handle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace VulkanCore 6 | { 7 | /// 8 | /// Handle to an unmanaged Vulkan resource. 9 | /// 10 | /// Handle type. 11 | public abstract class VulkanHandle where THandle : struct 12 | { 13 | /// 14 | /// Gets the handle to the unmanaged Vulkan resource. 15 | /// 16 | public THandle Handle { get; protected set; } 17 | 18 | /// 19 | /// Implicitly converts an instance of to its handle type. 20 | /// 21 | /// Instance to convert. 22 | public static implicit operator THandle(VulkanHandle value) => value?.Handle ?? default(THandle); 23 | } 24 | 25 | /// 26 | /// that implements dispose pattern as described in 27 | /// https://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.110%29.aspx and stores an allocator. 28 | /// 29 | /// Handle type. 30 | public abstract unsafe class DisposableHandle : VulkanHandle, IDisposable 31 | where THandle : struct 32 | { 33 | private AllocationCallbacks? _allocator; 34 | 35 | /// 36 | /// Allows the object to free unmanaged resources before it is reclaimed by garbage collection. 37 | /// 38 | ~DisposableHandle() 39 | { 40 | DisposeUnmanaged(); 41 | } 42 | 43 | /// 44 | /// Gets the memory allocator for the resource. This may be null. 45 | /// 46 | public AllocationCallbacks? Allocator 47 | { 48 | get { return _allocator; } 49 | protected set 50 | { 51 | _allocator = value; 52 | Interop.Free(NativeAllocator); 53 | NativeAllocator = null; 54 | if (_allocator.HasValue) 55 | { 56 | NativeAllocator = (AllocationCallbacks.Native*)Interop.Alloc(); 57 | _allocator.Value.ToNative(NativeAllocator); 58 | } 59 | } 60 | } 61 | 62 | internal AllocationCallbacks.Native* NativeAllocator { get; private set; } 63 | 64 | /// 65 | /// Gets if the instance is disposed. 66 | /// 67 | protected bool Disposed { get; private set; } 68 | 69 | /// 70 | /// Performs application-defined tasks associated with freeing, releasing, or resetting resources. 71 | /// 72 | public virtual void Dispose() 73 | { 74 | if (!Disposed) 75 | { 76 | DisposeUnmanaged(); 77 | GC.SuppressFinalize(this); 78 | Disposed = true; 79 | } 80 | } 81 | 82 | private void DisposeUnmanaged() 83 | { 84 | Interop.Free(NativeAllocator); 85 | } 86 | } 87 | 88 | /// 89 | /// Provides extensions methods for the class. 90 | /// 91 | public static class VulkanHandleExtensions 92 | { 93 | // We need to duplicate these extensions instead of using a generic one 94 | // due to compiler's inability to implicitly infer generic type params in this case. 95 | 96 | /// 97 | /// Creates an array of pointers from the sequence of types. 98 | /// 99 | /// A sequence to create an array from. 100 | /// An array that contains the pointers to the input handles. 101 | public static IntPtr[] ToHandleArray(this IEnumerable> values) 102 | => values.Select(val => val.Handle).ToArray(); 103 | 104 | /// 105 | /// Creates an array of pointers from the sequence of types. 106 | /// 107 | /// A sequence to create an array from. 108 | /// An array that contains the pointers to the input handles. 109 | public static long[] ToHandleArray(this IEnumerable> values) 110 | => values.Select(val => val.Handle).ToArray(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Src/Khr/CommandPoolExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Khr 4 | { 5 | /// 6 | /// Provides Khronos specific extension methods for the class. 7 | /// 8 | public static class CommandPoolExtensions 9 | { 10 | /// 11 | /// Trim a command pool. 12 | /// 13 | /// Trimming a command pool recycles unused memory from the command pool back to the system. 14 | /// 15 | /// Command buffers allocated from the pool are not affected by the command. 16 | /// 17 | /// The command pool to trim. 18 | public static void TrimKhr(this CommandPool commandPool) 19 | { 20 | vkTrimCommandPoolKHR(commandPool.Parent, commandPool, 0); 21 | } 22 | 23 | private delegate void vkTrimCommandPoolKHRDelegate(IntPtr device, long commandPool, CommandPoolTrimFlags flags); 24 | private static readonly vkTrimCommandPoolKHRDelegate vkTrimCommandPoolKHR = VulkanLibrary.GetStaticProc(nameof(vkTrimCommandPoolKHR)); 25 | } 26 | 27 | // Is reserved for future use. 28 | [Flags] 29 | internal enum CommandPoolTrimFlags 30 | { 31 | None = 0 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Src/Khr/DescriptorSetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Khr 4 | { 5 | /// 6 | /// Provides Khronos specific extension methods for the class. 7 | /// 8 | public static class DescriptorSetExtensions 9 | { 10 | /// 11 | /// Update the contents of a descriptor set object using an update template. 12 | /// 13 | /// The descriptor set to update. 14 | /// 15 | /// Specifies the update mapping between the application pointer and the descriptor set to update. 16 | /// 17 | /// 18 | /// A pointer to memory which contains one or more structures of , , or used to write the descriptors. 21 | /// 22 | public static void UpdateWithTemplateKhr(this DescriptorSet descriptorSet, 23 | DescriptorUpdateTemplateKhr descriptorUpdateTemplate, IntPtr data) 24 | { 25 | vkUpdateDescriptorSetWithTemplateKHR(descriptorSet.Parent.Parent, descriptorSet, descriptorUpdateTemplate, data); 26 | } 27 | 28 | private delegate void vkUpdateDescriptorSetWithTemplateKHRDelegate(IntPtr device, long descriptorSet, long descriptorUpdateTemplate, IntPtr data); 29 | private static readonly vkUpdateDescriptorSetWithTemplateKHRDelegate vkUpdateDescriptorSetWithTemplateKHR = VulkanLibrary.GetStaticProc(nameof(vkUpdateDescriptorSetWithTemplateKHR)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Src/Khr/DeviceMemoryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Khr 4 | { 5 | /// 6 | /// Provides Khronos specific extension methods for the class. 7 | /// 8 | public static unsafe class DeviceMemoryExtensions 9 | { 10 | /// 11 | /// Get a Windows HANDLE for a memory object. 12 | /// 13 | /// The memory object from which the handle will be exported. 14 | /// The type of handle requested. 15 | /// The Windows handle representing the underlying resources of the device memory object. 16 | /// Vulkan returns an error code. 17 | public static IntPtr GetWin32HandleKhr(this DeviceMemory memory, ExternalMemoryHandleTypesKhr handleType) 18 | { 19 | IntPtr handle; 20 | Result result = vkGetMemoryWin32HandleKHR(memory)(memory.Parent, memory, handleType, &handle); 21 | VulkanException.ThrowForInvalidResult(result); 22 | return handle; 23 | } 24 | 25 | /// 26 | /// Get a POSIX file descriptor for a memory object. 27 | /// 28 | /// The memory object from which the handle will be exported. 29 | /// The type of handle requested. 30 | /// A file descriptor representing the underlying resources of the device memory object. 31 | /// Vulkan returns an error code. 32 | public static int GetFdKhr(this DeviceMemory memory, ExternalMemoryHandleTypesKhr handleType) 33 | { 34 | int fd; 35 | Result result = vkGetMemoryFdKHR(memory)(memory.Parent, memory, handleType, &fd); 36 | VulkanException.ThrowForInvalidResult(result); 37 | return fd; 38 | } 39 | 40 | private delegate Result vkGetMemoryWin32HandleKHRDelegate(IntPtr device, long memory, ExternalMemoryHandleTypesKhr handleType, IntPtr* handle); 41 | private static vkGetMemoryWin32HandleKHRDelegate vkGetMemoryWin32HandleKHR(DeviceMemory memory) => GetProc(memory, nameof(vkGetMemoryWin32HandleKHR)); 42 | 43 | private delegate Result vkGetMemoryFdKHRDelegate(IntPtr device, long memory, ExternalMemoryHandleTypesKhr handleType, int* fd); 44 | private static vkGetMemoryFdKHRDelegate vkGetMemoryFdKHR(DeviceMemory memory) => GetProc(memory, nameof(vkGetMemoryFdKHR)); 45 | 46 | private static TDelegate GetProc(DeviceMemory memory, string name) where TDelegate : class => memory.Parent.GetProc(name); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Src/Khr/DisplayKhr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Khr 4 | { 5 | /// 6 | /// Opaque handle to a display object. 7 | /// 8 | public unsafe class DisplayKhr : VulkanHandle 9 | { 10 | internal DisplayKhr(PhysicalDevice parent, long handle) 11 | { 12 | Parent = parent; 13 | Handle = handle; 14 | } 15 | 16 | /// 17 | /// Gets the parent of this resource. 18 | /// 19 | public PhysicalDevice Parent { get; } 20 | 21 | /// 22 | /// Query display supported modes. 23 | /// Each display has one or more supported modes associated with it by default. 24 | /// 25 | /// An array of structures. 26 | /// Vulkan returns an error code. 27 | public DisplayModePropertiesKhr[] GetDisplayModeProperties() 28 | { 29 | int count; 30 | Result result = vkGetDisplayModePropertiesKHR(Parent, this, &count, null); 31 | VulkanException.ThrowForInvalidResult(result); 32 | 33 | var properties = new DisplayModePropertiesKhr[count]; 34 | fixed (DisplayModePropertiesKhr* propertiesPtr = properties) 35 | result = vkGetDisplayModePropertiesKHR(Parent, this, &count, propertiesPtr); 36 | VulkanException.ThrowForInvalidResult(result); 37 | return properties; 38 | } 39 | 40 | private delegate Result vkGetDisplayModePropertiesKHRDelegate(IntPtr physicalDevice, long display, int* propertyCount, DisplayModePropertiesKhr* properties); 41 | private static readonly vkGetDisplayModePropertiesKHRDelegate vkGetDisplayModePropertiesKHR = VulkanLibrary.GetStaticProc(nameof(vkGetDisplayModePropertiesKHR)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Src/Khr/SemaphoreExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Khr 4 | { 5 | /// 6 | /// Provides Khronos specific extension methods for the class. 7 | /// 8 | public static unsafe class SemaphoreExtensions 9 | { 10 | /// 11 | /// Get a Windows HANDLE for a semaphore. 12 | /// 13 | /// The semaphore from which state will be exported. 14 | /// The type of handle requested. 15 | /// The Windows handle representing the semaphore state. 16 | /// Vulkan returns an error code. 17 | public static IntPtr GetWin32HandleKhr(this Semaphore semaphore, ExternalSemaphoreHandleTypesKhr handleType) 18 | { 19 | IntPtr handle; 20 | Result result = vkGetSemaphoreWin32HandleKHR(semaphore)(semaphore.Parent, semaphore, handleType, &handle); 21 | VulkanException.ThrowForInvalidResult(result); 22 | return handle; 23 | } 24 | 25 | /// 26 | /// Get a POSIX file descriptor handle for a semaphore. 27 | /// 28 | /// The semaphore from which state will be exported. 29 | /// The type of handle requested. 30 | /// The file descriptor representing the semaphore state. 31 | /// Vulkan returns an error code. 32 | public static int GetFdKhr(this Semaphore semaphore, ExternalSemaphoreHandleTypesKhr handleType) 33 | { 34 | int fd; 35 | Result result = vkGetSemaphoreFdKHR(semaphore)(semaphore.Parent, semaphore, handleType, &fd); 36 | VulkanException.ThrowForInvalidResult(result); 37 | return fd; 38 | } 39 | 40 | private delegate Result vkGetSemaphoreWin32HandleKHRDelegate(IntPtr device, long semaphore, ExternalSemaphoreHandleTypesKhr handleType, IntPtr* handle); 41 | private static vkGetSemaphoreWin32HandleKHRDelegate vkGetSemaphoreWin32HandleKHR(Semaphore semaphore) => GetProc(semaphore, nameof(vkGetSemaphoreWin32HandleKHR)); 42 | 43 | private delegate Result vkGetSemaphoreFdKHXDelegate(IntPtr device, long semaphore, ExternalSemaphoreHandleTypesKhr handleType, int* fd); 44 | private static vkGetSemaphoreFdKHXDelegate vkGetSemaphoreFdKHR(Semaphore semaphore) => GetProc(semaphore, nameof(vkGetSemaphoreFdKHR)); 45 | 46 | private static TDelegate GetProc(Semaphore semaphore, string name) where TDelegate : class => semaphore.Parent.GetProc(name); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Src/Khx/InstanceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Khx 5 | { 6 | /// 7 | /// Provides experimental Khronos specific extension methods for the class. 8 | /// 9 | public static unsafe class InstanceExtensions 10 | { 11 | /// 12 | /// Enumerates groups of physical devices that can be used to create a single logical device. 13 | /// 14 | /// A handle to a previously created Vulkan instance. 15 | /// An array of structures. 16 | /// Vulkan returns an error code. 17 | public static PhysicalDeviceGroupPropertiesKhx[] EnumeratePhysicalDeviceGroupsKhx(this Instance instance) 18 | { 19 | int count; 20 | Result result = vkEnumeratePhysicalDeviceGroupsKHX(instance)(instance, &count, null); 21 | VulkanException.ThrowForInvalidResult(result); 22 | 23 | var nativeProperties = new PhysicalDeviceGroupPropertiesKhx.Native[count]; 24 | result = vkEnumeratePhysicalDeviceGroupsKHX(instance)(instance, &count, nativeProperties); 25 | VulkanException.ThrowForInvalidResult(result); 26 | 27 | var groupProperties = new PhysicalDeviceGroupPropertiesKhx[count]; 28 | for (int i = 0; i < count; i++) 29 | PhysicalDeviceGroupPropertiesKhx.FromNative(ref nativeProperties[i], instance, out groupProperties[i]); 30 | return groupProperties; 31 | } 32 | 33 | private delegate Result vkEnumeratePhysicalDeviceGroupsKHXDelegate(IntPtr instance, int* physicalDeviceGroupCount, [Out]PhysicalDeviceGroupPropertiesKhx.Native[] physicalDeviceGroupProperties); 34 | private static vkEnumeratePhysicalDeviceGroupsKHXDelegate vkEnumeratePhysicalDeviceGroupsKHX(Instance instance) => instance.GetProc(nameof(vkEnumeratePhysicalDeviceGroupsKHX)); 35 | } 36 | 37 | /// 38 | /// Structure specifying physical device group properties. 39 | /// 40 | public struct PhysicalDeviceGroupPropertiesKhx 41 | { 42 | /// 43 | /// Is or a pointer to an extension-specific structure. 44 | /// 45 | public IntPtr Next; 46 | /// 47 | /// An array of physical device handles representing all physical devices in the group. 48 | /// 49 | public PhysicalDevice[] PhysicalDevices; 50 | /// 51 | /// Indicates whether logical devices created from the group support allocating device memory 52 | /// on a subset of devices, via the 53 | /// member. If this is false, then all device memory allocations are made across all 54 | /// physical devices in the group. If length is 1, then must be false. 56 | /// 57 | public Bool SubsetAllocation; 58 | 59 | [StructLayout(LayoutKind.Sequential)] 60 | internal struct Native 61 | { 62 | public StructureType Type; 63 | public IntPtr Next; 64 | public int PhysicalDeviceCount; 65 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constant.MaxDeviceGroupSizeKhx)] 66 | public IntPtr[] PhysicalDevices; 67 | public Bool SubsetAllocation; 68 | } 69 | 70 | internal static void FromNative(ref Native native, Instance instance, out PhysicalDeviceGroupPropertiesKhx managed) 71 | { 72 | managed.Next = native.Next; 73 | managed.PhysicalDevices = new PhysicalDevice[native.PhysicalDeviceCount]; 74 | for (int i = 0; i < native.PhysicalDeviceCount; i++) 75 | managed.PhysicalDevices[i] = new PhysicalDevice(native.PhysicalDevices[i], instance); 76 | managed.SubsetAllocation = native.SubsetAllocation; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Src/Khx/PhysicalDeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using VulkanCore.Khr; 4 | using static VulkanCore.Constant; 5 | 6 | namespace VulkanCore.Khx 7 | { 8 | /// 9 | /// Provides experimental Khronos specific extension methods for the class. 10 | /// 11 | public static unsafe class PhysicalDeviceExtensions 12 | { 13 | /// 14 | /// Query present rectangles for a surface on a physical device. 15 | /// 16 | /// When using , the application may 17 | /// need to know which regions of the surface are used when presenting locally on each 18 | /// physical device. 19 | /// 20 | /// 21 | /// Presentation of swapchain images to this surface need only have valid contents in the 22 | /// regions returned by this command. 23 | /// 24 | /// 25 | /// The physical device. 26 | /// The surface. 27 | /// An array of structures. 28 | /// Vulkan returns an error code. 29 | public static Rect2D[] GetPresentRectanglesKhx(this PhysicalDevice physicalDevice, SurfaceKhr surface) 30 | { 31 | int count; 32 | Result result = vkGetPhysicalDevicePresentRectanglesKHX(physicalDevice)(physicalDevice, surface, &count, null); 33 | VulkanException.ThrowForInvalidResult(result); 34 | 35 | var rectangles = new Rect2D[count]; 36 | fixed (Rect2D* rectanglesPtr = rectangles) 37 | { 38 | result = vkGetPhysicalDevicePresentRectanglesKHX(physicalDevice)(physicalDevice, surface, &count, rectanglesPtr); 39 | VulkanException.ThrowForInvalidResult(result); 40 | return rectangles; 41 | } 42 | } 43 | 44 | private delegate Result vkGetPhysicalDevicePresentRectanglesKHXDelegate(IntPtr physicalDevice, long surface, int* rectCount, Rect2D* rects); 45 | private static vkGetPhysicalDevicePresentRectanglesKHXDelegate vkGetPhysicalDevicePresentRectanglesKHX(PhysicalDevice physicalDevice) => GetProc(physicalDevice, nameof(vkGetPhysicalDevicePresentRectanglesKHX)); 46 | 47 | private static TDelegate GetProc(PhysicalDevice physicalDevice, string name) where TDelegate : class => physicalDevice.Parent.GetProc(name); 48 | } 49 | 50 | /// 51 | /// Structure describing multiview limits that can be supported by an implementation. 52 | /// 53 | [StructLayout(LayoutKind.Sequential)] 54 | public struct PhysicalDeviceMultiviewPropertiesKhx 55 | { 56 | internal StructureType Type; 57 | 58 | /// 59 | /// Pointer to next structure. 60 | /// 61 | public IntPtr Next; 62 | /// 63 | /// Max number of views in a subpass. 64 | /// 65 | public int MaxMultiviewViewCount; 66 | /// 67 | /// Max instance index for a draw in a multiview subpass. 68 | /// 69 | public int MaxMultiviewInstanceIndex; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Src/Mvk/DeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore.Mvk 4 | { 5 | /// 6 | /// Provides Brenwill Workshop specific extension methods for the class. 7 | /// 8 | public static unsafe class DeviceExtensions 9 | { 10 | /// 11 | /// Get the current structure for this device 12 | /// 13 | /// The device to get configuration from. 14 | /// The configuration structure 15 | public static MVKDeviceConfiguration GetMVKDeviceConfiguration(this Device device) 16 | { 17 | MVKDeviceConfiguration configuration; 18 | vkGetMoltenVKDeviceConfigurationMVK(device)(device, &configuration); 19 | return configuration; 20 | } 21 | 22 | /// 23 | /// Sets the current structure for this device 24 | /// 25 | /// The device to set the configuration to. 26 | /// Structure containing the configuration parameters. 27 | /// Vulkan returns an error code. 28 | public static void SetMVKDeviceConfiguration(this Device device, MVKDeviceConfiguration configuration) 29 | { 30 | Result result = vkSetMoltenVKDeviceConfigurationMVK(device)(device, &configuration); 31 | VulkanException.ThrowForInvalidResult(result); 32 | } 33 | 34 | private delegate void vkGetMoltenVKDeviceConfigurationMVKDelegate(IntPtr device, MVKDeviceConfiguration* configuration); 35 | private static vkGetMoltenVKDeviceConfigurationMVKDelegate vkGetMoltenVKDeviceConfigurationMVK(Device device) => device.GetProc(nameof(vkGetMoltenVKDeviceConfigurationMVK)); 36 | 37 | private delegate Result vkSetMoltenVKDeviceConfigurationMVKDelegate(IntPtr device, MVKDeviceConfiguration* configuration); 38 | private static vkSetMoltenVKDeviceConfigurationMVKDelegate vkSetMoltenVKDeviceConfigurationMVK(Device device) => device.GetProc(nameof(vkSetMoltenVKDeviceConfigurationMVK)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Src/NN/InstanceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using VulkanCore.Khr; 4 | 5 | namespace VulkanCore.NN 6 | { 7 | /// 8 | /// Provides Nintendo specific extension methods for the class. 9 | /// 10 | public static unsafe class InstanceExtensions 11 | { 12 | /// 13 | /// Create a object for a VI layer. 14 | /// 15 | /// During the lifetime of a surface created using a particular `NativeWindowHandle`, any 16 | /// attempts to create another surface for the same `Layer` and any attempts to connect to 17 | /// the same layer through other platform mechanisms will have undefined results. 18 | /// 19 | /// 20 | /// The of a VI surface is always 21 | /// undefined. Applications are expected to choose an appropriate size for the swapchain's 22 | /// (e.g., by matching the the result of a 23 | /// call to `GetDisplayResolution`). 24 | /// 25 | /// 26 | /// The to associate with the surface. 27 | /// 28 | /// The structure containing the parameters affecting the creation of the surface object. 29 | /// 30 | /// 31 | /// The allocator used for host memory allocated for the surface object. 32 | /// 33 | /// The resulting surface object handle. 34 | /// Vulkan returns an error code. 35 | public static SurfaceKhr CreateVISurfaceNN(this Instance instance, 36 | VISurfaceCreateInfoNN createInfo, AllocationCallbacks? allocator = null) 37 | { 38 | createInfo.Prepare(); 39 | AllocationCallbacks.Native* nativeAllocator = null; 40 | if (allocator.HasValue) 41 | { 42 | nativeAllocator = (AllocationCallbacks.Native*)Interop.Alloc(); 43 | allocator.Value.ToNative(nativeAllocator); 44 | } 45 | 46 | long handle; 47 | Result result = vkCreateViSurfaceNN(instance)(instance, &createInfo, nativeAllocator, &handle); 48 | 49 | Interop.Free(nativeAllocator); 50 | 51 | VulkanException.ThrowForInvalidResult(result); 52 | return new SurfaceKhr(instance, ref allocator, handle); 53 | } 54 | 55 | private delegate Result vkCreateViSurfaceNNDelegate(IntPtr instance, VISurfaceCreateInfoNN* createInfo, AllocationCallbacks.Native* allocator, long* surface); 56 | private static vkCreateViSurfaceNNDelegate vkCreateViSurfaceNN(Instance instance) => instance.GetProc(nameof(vkCreateViSurfaceNN)); 57 | } 58 | 59 | /// 60 | /// Structure specifying parameters of a newly created VI surface object. 61 | /// 62 | [StructLayout(LayoutKind.Sequential)] 63 | public struct VISurfaceCreateInfoNN 64 | { 65 | internal StructureType Type; 66 | internal IntPtr Next; 67 | internal VISurfaceCreateFlagsNN Flags; 68 | 69 | /// 70 | /// The `NativeWindowHandle` for the `Layer` with which to associate the surface. 71 | /// 72 | public IntPtr Window; 73 | 74 | internal void Prepare() 75 | { 76 | Type = StructureType.VISurfaceCreateInfoNN; 77 | } 78 | } 79 | 80 | [Flags] 81 | internal enum VISurfaceCreateFlagsNN 82 | { 83 | None = 0 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Src/Nvx/DeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace VulkanCore.Nvx 2 | { 3 | /// 4 | /// Provides NVIDIA specific extension methods for the class. 5 | /// 6 | public static class DeviceExtensions 7 | { 8 | /// Vulkan returns an error code. 9 | public static IndirectCommandsLayoutNvx CreateIndirectCommandsLayoutNvx(this Device device, 10 | IndirectCommandsLayoutCreateInfoNvx createInfo, AllocationCallbacks? allocator = null) 11 | { 12 | return new IndirectCommandsLayoutNvx(device, ref createInfo, ref allocator); 13 | } 14 | 15 | /// Vulkan returns an error code. 16 | public static ObjectTableNvx CreateObjectTableNvx(this Device device, 17 | ObjectTableCreateInfoNvx createInfo, AllocationCallbacks? allocator = null) 18 | { 19 | return new ObjectTableNvx(device, ref createInfo, ref allocator); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Src/Nvx/PhysicalDeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore.Nvx 5 | { 6 | /// 7 | /// Provides NVIDIA specific extension methods for the class. 8 | /// 9 | public static unsafe class PhysicalDeviceExtensions 10 | { 11 | /// 12 | /// Returns device-generated commands related properties of a physical device. 13 | /// 14 | /// 15 | /// The handle to the physical device whose properties will be queried. 16 | /// 17 | /// Structures that will be filled with returned information. 18 | public static (DeviceGeneratedCommandsFeaturesNvx, DeviceGeneratedCommandsLimitsNvx) GetGeneratedCommandsPropertiesNvx( 19 | this PhysicalDevice physicalDevice) 20 | { 21 | DeviceGeneratedCommandsFeaturesNvx features; 22 | DeviceGeneratedCommandsLimitsNvx limits; 23 | vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(physicalDevice)(physicalDevice, &features, &limits); 24 | return (features, limits); 25 | } 26 | 27 | private delegate void vkGetPhysicalDeviceGeneratedCommandsPropertiesNVXDelegate(IntPtr physicalDevice, DeviceGeneratedCommandsFeaturesNvx* features, DeviceGeneratedCommandsLimitsNvx* limits); 28 | private static vkGetPhysicalDeviceGeneratedCommandsPropertiesNVXDelegate vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(PhysicalDevice physicalDevice) => physicalDevice.Parent.GetProc(nameof(vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)); 29 | } 30 | 31 | /// 32 | /// Structure specifying physical device support. 33 | /// 34 | [StructLayout(LayoutKind.Sequential)] 35 | public struct DeviceGeneratedCommandsFeaturesNvx 36 | { 37 | internal StructureType Type; 38 | internal IntPtr Next; 39 | 40 | /// 41 | /// Indicates whether the supports entries with bit set and supports . 44 | /// 45 | public Bool ComputeBindingPointSupport; 46 | } 47 | 48 | /// 49 | /// Structure specifying physical device limits. 50 | /// 51 | [StructLayout(LayoutKind.Sequential)] 52 | public struct DeviceGeneratedCommandsLimitsNvx 53 | { 54 | internal StructureType Type; 55 | internal IntPtr Next; 56 | 57 | /// 58 | /// The maximum number of tokens in . 59 | /// 60 | public int MaxIndirectCommandsLayoutTokenCount; 61 | /// 62 | /// The maximum number of entries per resource type in . 63 | /// 64 | public int MaxObjectEntryCounts; 65 | /// 66 | /// The minimum alignment for memory addresses optionally used in . 67 | /// 68 | public int MinSequenceCountBufferOffsetAlignment; 69 | /// 70 | /// The minimum alignment for memory addresses optionally used in . 71 | /// 72 | public int MinSequenceIndexBufferOffsetAlignment; 73 | /// 74 | /// The minimum alignment for memory addresses optionally used in . 75 | /// 76 | public int MinCommandsTokenBufferOffsetAlignment; 77 | } 78 | 79 | /// 80 | /// Structure describing multiview limits that can be supported by an implementation. 81 | /// 82 | [StructLayout(LayoutKind.Sequential)] 83 | public struct PhysicalDeviceMultiviewPerViewAttributesPropertiesNvx 84 | { 85 | internal StructureType Type; 86 | 87 | /// 88 | /// Pointer to next structure. 89 | /// 90 | public IntPtr Next; 91 | /// 92 | /// Is true if the implementation supports per-view position values that differ in 93 | /// components other than the X component. 94 | /// 95 | public Bool PerViewPositionAllComponents; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Src/ObjectType.cs: -------------------------------------------------------------------------------- 1 | namespace VulkanCore 2 | { 3 | /// 4 | /// Specify an enumeration to track object handle types. 5 | /// 6 | /// The enumeration defines values, each of which corresponds to a specific Vulkan handle type. 7 | /// These values can be used to associate debug information with a particular type of object 8 | /// through one or more extensions. 9 | /// 10 | /// 11 | public enum ObjectType 12 | { 13 | Unknown = 0, 14 | Instance = 1, 15 | PhysicalDevice = 2, 16 | Device = 3, 17 | Queue = 4, 18 | Semaphore = 5, 19 | CommandBuffer = 6, 20 | Fence = 7, 21 | DeviceMemory = 8, 22 | Buffer = 9, 23 | Image = 10, 24 | Event = 11, 25 | QueryPool = 12, 26 | BufferView = 13, 27 | ImageView = 14, 28 | ShaderModule = 15, 29 | PipelineCache = 16, 30 | PipelineLayout = 17, 31 | RenderPass = 18, 32 | Pipeline = 19, 33 | DescriptorSetLayout = 20, 34 | Sampler = 21, 35 | DescriptorPool = 22, 36 | DescriptorSet = 23, 37 | Framebuffer = 24, 38 | CommandPool = 25, 39 | SurfaceKhr = 1000000000, 40 | SwapchainKhr = 1000001000, 41 | DisplayKhr = 1000002000, 42 | DisplayModeKhr = 1000002001, 43 | DebugReportCallbackExt = 1000011000, 44 | DescriptorUpdateTemplateKhr = 1000085000, 45 | ObjectTableNvx = 1000086000, 46 | IndirectCommandsLayoutNvx = 1000086001, 47 | SamplerYcbcrConversionKhr = 1000156000, 48 | ValidationCacheExt = 1000160000 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Src/Semaphore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore 5 | { 6 | /// 7 | /// Opaque handle to a semaphore object. 8 | /// 9 | /// Semaphores are a synchronization primitive that can be used to insert a dependency between 10 | /// batches submitted to queues. Semaphores have two states - signaled and unsignaled. The state 11 | /// of a semaphore can be signaled after execution of a batch of commands is completed. A batch 12 | /// can wait for a semaphore to become signaled before it begins execution, and the semaphore is 13 | /// also unsignaled before the batch begins execution. 14 | /// 15 | /// 16 | public unsafe class Semaphore : DisposableHandle 17 | { 18 | internal Semaphore(Device parent, ref AllocationCallbacks? allocator) 19 | { 20 | Parent = parent; 21 | Allocator = allocator; 22 | 23 | var createInfo = new SemaphoreCreateInfo(); 24 | createInfo.Prepare(); 25 | 26 | long handle; 27 | Result result = vkCreateSemaphore(Parent, &createInfo, NativeAllocator, &handle); 28 | VulkanException.ThrowForInvalidResult(result); 29 | Handle = handle; 30 | } 31 | 32 | internal Semaphore(long handle, Device parent) 33 | { 34 | Handle = handle; 35 | Parent = parent; 36 | } 37 | 38 | /// 39 | /// Gets the parent of this resource. 40 | /// 41 | public Device Parent { get; } 42 | 43 | /// 44 | /// Destroy a semaphore object. 45 | /// 46 | public override void Dispose() 47 | { 48 | if (!Disposed) vkDestroySemaphore(Parent, this, NativeAllocator); 49 | base.Dispose(); 50 | } 51 | 52 | private delegate Result vkCreateSemaphoreDelegate(IntPtr device, SemaphoreCreateInfo* createInfo, AllocationCallbacks.Native* allocator, long* semaphore); 53 | private static readonly vkCreateSemaphoreDelegate vkCreateSemaphore = VulkanLibrary.GetStaticProc(nameof(vkCreateSemaphore)); 54 | 55 | private delegate void vkDestroySemaphoreDelegate(IntPtr device, long semaphore, AllocationCallbacks.Native* allocator); 56 | private static readonly vkDestroySemaphoreDelegate vkDestroySemaphore = VulkanLibrary.GetStaticProc(nameof(vkDestroySemaphore)); 57 | } 58 | 59 | /// 60 | /// Structure specifying parameters of a newly created semaphore. 61 | /// 62 | [StructLayout(LayoutKind.Sequential)] 63 | internal struct SemaphoreCreateInfo 64 | { 65 | public StructureType Type; 66 | public IntPtr Next; 67 | public SemaphoreCreateFlags Flags; 68 | 69 | public void Prepare() 70 | { 71 | Type = StructureType.SemaphoreCreateInfo; 72 | } 73 | } 74 | 75 | // Is reserved for future use. 76 | [Flags] 77 | internal enum SemaphoreCreateFlags 78 | { 79 | None = 0 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Src/ShaderModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace VulkanCore 5 | { 6 | /// 7 | /// Opaque handle to a shader module object. 8 | /// 9 | /// Shader modules contain shader code and one or more entry points. Shaders are selected from a 10 | /// shader module by specifying an entry point as part of pipeline creation. The stages of a 11 | /// pipeline can use shaders that come from different modules. The shader code defining a shader 12 | /// module must be in the SPIR-V format. 13 | /// 14 | /// 15 | public unsafe class ShaderModule : DisposableHandle 16 | { 17 | internal ShaderModule(Device parent, ref ShaderModuleCreateInfo createInfo, ref AllocationCallbacks? allocator) 18 | { 19 | Parent = parent; 20 | Allocator = allocator; 21 | 22 | fixed (byte* codePtr = createInfo.Code) 23 | { 24 | createInfo.ToNative(out ShaderModuleCreateInfo.Native nativeCreateInfo, codePtr); 25 | long handle; 26 | Result result = vkCreateShaderModule(Parent, &nativeCreateInfo, NativeAllocator, &handle); 27 | VulkanException.ThrowForInvalidResult(result); 28 | Handle = handle; 29 | } 30 | } 31 | 32 | /// 33 | /// Gets the owner of the resource. 34 | /// 35 | public Device Parent { get; } 36 | 37 | /// 38 | /// Destroy a shader module. 39 | /// 40 | public override void Dispose() 41 | { 42 | if (!Disposed) vkDestroyShaderModule(Parent, this, NativeAllocator); 43 | base.Dispose(); 44 | } 45 | 46 | private delegate Result vkCreateShaderModuleDelegate(IntPtr device, ShaderModuleCreateInfo.Native* createInfo, AllocationCallbacks.Native* allocator, long* shaderModule); 47 | private static readonly vkCreateShaderModuleDelegate vkCreateShaderModule = VulkanLibrary.GetStaticProc(nameof(vkCreateShaderModule)); 48 | 49 | private delegate void vkDestroyShaderModuleDelegate(IntPtr device, long shaderModule, AllocationCallbacks.Native* allocator); 50 | private static readonly vkDestroyShaderModuleDelegate vkDestroyShaderModule = VulkanLibrary.GetStaticProc(nameof(vkDestroyShaderModule)); 51 | } 52 | 53 | /// 54 | /// Structure specifying parameters of a newly created shader module. 55 | /// 56 | public unsafe struct ShaderModuleCreateInfo 57 | { 58 | /// 59 | /// The code that is used to create the shader module. The type and format of the code is 60 | /// determined from the content of the code. 61 | /// 62 | public byte[] Code; 63 | 64 | /// 65 | /// Initializes a new instance of the structure. 66 | /// 67 | /// 68 | /// The code that is used to create the shader module. The type and format of the code is 69 | /// determined from the content of the code. 70 | /// 71 | public ShaderModuleCreateInfo(byte[] code) 72 | { 73 | Code = code; 74 | } 75 | 76 | [StructLayout(LayoutKind.Sequential)] 77 | internal struct Native 78 | { 79 | public StructureType Type; 80 | public IntPtr Next; 81 | public ShaderModuleCreateFlags Flags; 82 | public Size CodeSize; 83 | public byte* Code; 84 | } 85 | 86 | internal void ToNative(out Native native, byte* code) 87 | { 88 | native.Type = StructureType.ShaderModuleCreateInfo; 89 | native.Next = IntPtr.Zero; 90 | native.Flags = 0; 91 | native.CodeSize = Code?.Length ?? 0; 92 | native.Code = code; 93 | } 94 | } 95 | 96 | // Is reserved for future use. 97 | internal enum ShaderModuleCreateFlags 98 | { 99 | None = 0 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Src/UtilityExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace VulkanCore 6 | { 7 | /// 8 | /// Provides helper methods for various types. 9 | /// 10 | public static class UtilityExtensions 11 | { 12 | /// 13 | /// Gets the index of the that has all the requested set or -1 if not found. 15 | /// 16 | /// 17 | /// Structures describing the memory types that can be used to access memory allocated from 18 | /// the heaps specified by . 19 | /// 20 | /// 21 | /// A bitmask of that contains one bit set 22 | /// for every memory type supported by the resource. 23 | /// 24 | /// A bitmask of properties to request. 25 | /// Index of the requested or -1 if not found. 26 | /// /// 27 | /// is null. 28 | public static int IndexOf(this IList memoryTypes, int memoryTypeBits, MemoryProperties properties) 29 | { 30 | if (memoryTypes == null) 31 | throw new ArgumentNullException(nameof(memoryTypes)); 32 | 33 | int count = memoryTypes?.Count ?? 0; 34 | for (int i = 0; i < count; i++) 35 | { 36 | if ((memoryTypeBits & 1) == 1 && 37 | (memoryTypes[i].PropertyFlags & properties) == properties) 38 | { 39 | return i; 40 | } 41 | memoryTypeBits >>= 1; 42 | } 43 | return -1; 44 | } 45 | 46 | /// 47 | /// Determines whether a sequence of contains a layer with 48 | /// specified . 49 | /// 50 | /// A sequence in which to locate a layer name. 51 | /// The layer name to locate in the sequence. 52 | /// 53 | /// true if the source sequence contains an element that has the specified value; 54 | /// otherwise, false. 55 | /// 56 | /// is null. 57 | public static bool Contains(this IEnumerable layers, string name) 58 | { 59 | return layers 60 | .Select(layer => layer.LayerName) 61 | .Contains(name, StringComparer.Ordinal); 62 | } 63 | 64 | /// 65 | /// Determines whether a sequence of contains a layer with 66 | /// specified . 67 | /// 68 | /// A sequence in which to locate an extension name. 69 | /// The layer name to locate in the sequence. 70 | /// 71 | /// true if the source sequence contains an element that has the specified value; 72 | /// otherwise, false. 73 | /// 74 | /// is null. 75 | public static bool Contains(this IEnumerable extensions, string name) 76 | { 77 | return extensions 78 | .Select(extension => extension.ExtensionName) 79 | .Contains(name, StringComparer.Ordinal); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Src/Version.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace VulkanCore 4 | { 5 | /// 6 | /// Semantic Versioning number. 7 | /// 8 | /// http://semver.org/ 9 | public struct Version : IEquatable, IComparable 10 | { 11 | private readonly int _value; 12 | 13 | /// 14 | /// Initializes a new instance of the struct. 15 | /// 16 | /// Major component of semver. 17 | /// Minor component of semver. 18 | /// Patch component of semver. 19 | public Version(int major, int minor, int patch) 20 | { 21 | _value = major << 22 | minor << 12 | patch; 22 | } 23 | 24 | /// 25 | /// Gets the major component of semver. 26 | /// 27 | public int Major => _value >> 22; 28 | /// 29 | /// Gets the minor component of semver. 30 | /// 31 | public int Minor => (_value >> 12) & 0x03FF; 32 | /// 33 | /// Gets the patch component of semver. 34 | /// 35 | public int Patch => _value & 0x0FFF; 36 | 37 | /// 38 | /// Returns a string that represents the current version in the form of MAJOR.MINOR.PATCH. 39 | /// 40 | /// A string that represents the current version. 41 | public override string ToString() => $"{Major}.{Minor}.{Patch}"; 42 | 43 | /// 44 | /// Indicates whether the current version is equal to another version. 45 | /// 46 | /// A version to compare with this version. 47 | /// 48 | /// true if the current version is equal to the other parameter; otherwise, false. 49 | /// 50 | public bool Equals(Version other) => _value == other._value; 51 | 52 | /// 53 | /// Compares the current instance with another version and returns an integer that indicates 54 | /// whether the current instance precedes, follows, or occurs in the same position in the 55 | /// sort order as the other version. 56 | /// 57 | /// A version to compare with this instance. 58 | /// A value that indicates the relative order of the versions being compared. 59 | public int CompareTo(Version other) => _value.CompareTo(other._value); 60 | 61 | /// 62 | /// A shorthand for writing new Version(0, 0, 0). 63 | /// 64 | public static Version Zero => new Version(0, 0, 0); 65 | 66 | public static implicit operator int(Version version) 67 | { 68 | return version._value; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Src/VulkanCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | True 5 | discosultan 6 | Vulkan bindings for .NET Standard 7 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 8 | 13 | $(NoWarn);CS1591;IDE1006 14 | https://raw.githubusercontent.com/discosultan/VulkanCore/master/Doc/Vulkan64.png 15 | https://raw.githubusercontent.com/discosultan/VulkanCore/master/LICENSE 16 | https://github.com/discosultan/VulkanCore 17 | https://github.com/discosultan/VulkanCore/releases 18 | https://github.com/discosultan/VulkanCore 19 | netstandard1.3;net5.0 20 | 1.0.0-alpha40 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Src/VulkanException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace VulkanCore 5 | { 6 | /// 7 | /// Represents an error from executing a Vulkan command. 8 | /// 9 | public class VulkanException : Exception 10 | { 11 | private const string DefaultMessage = "Vulkan command failed to execute."; 12 | 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The result returned by Vulkan. 17 | /// The message that describes the error. 18 | public VulkanException(Result result, string message = DefaultMessage) 19 | : base($"[{(int)result}] {result} - {message}") 20 | { 21 | Result = result; 22 | } 23 | 24 | /// 25 | /// Gets the result returned by Vulkan. 26 | /// 27 | public Result Result { get; } 28 | 29 | /// 30 | /// Gets if the result is considered an error. 31 | /// 32 | public bool IsError => Result < 0; 33 | 34 | [DebuggerHidden] 35 | [DebuggerStepThrough] 36 | internal static void ThrowForInvalidResult(Result result) 37 | { 38 | if (result != Result.Success) 39 | throw new VulkanException(result); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/BoolTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class BoolTest 7 | { 8 | [Fact] 9 | public void ImplicitConversions() 10 | { 11 | Bool boolTrue = true; 12 | Bool boolFalse = false; 13 | Bool intTrue = 1; 14 | Bool intFalse = 0; 15 | 16 | Assert.True(boolTrue); 17 | Assert.False(boolFalse); 18 | Assert.Equal(1, (int)intTrue); 19 | Assert.Equal(0, (int)intFalse); 20 | } 21 | 22 | [Fact] 23 | public void BoolEquals() 24 | { 25 | Bool boolTrue = true; 26 | Bool boolFalse = false; 27 | 28 | Assert.True(boolTrue.Equals(boolTrue)); 29 | Assert.False(boolTrue.Equals(boolFalse)); 30 | Assert.True(boolTrue == boolTrue); 31 | Assert.False(boolTrue == boolFalse); 32 | Assert.False(boolTrue != boolTrue); 33 | Assert.True(boolTrue != boolFalse); 34 | Assert.Equal(true.GetHashCode(), boolTrue.GetHashCode()); 35 | Assert.Equal(false.GetHashCode(), boolFalse.GetHashCode()); 36 | } 37 | 38 | [Fact] 39 | public void ConvertToString() 40 | { 41 | Bool boolTrue = true; 42 | Bool boolFalse = false; 43 | 44 | Assert.Equal(true.ToString(), boolTrue.ToString()); 45 | Assert.Equal(false.ToString(), boolFalse.ToString()); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/BufferTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class BufferTest : HandleTestBase 8 | { 9 | private const int DefaultBufferSize = 32; 10 | 11 | [Fact] 12 | public void GetMemoryRequirements() 13 | { 14 | using (Buffer buffer = CreateBuffer()) 15 | { 16 | buffer.GetMemoryRequirements(); 17 | } 18 | } 19 | 20 | [Fact] 21 | public void BindMemoryAndCreateBufferView() 22 | { 23 | using (Buffer buffer = CreateBuffer()) 24 | { 25 | PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties(); 26 | MemoryRequirements memReq = buffer.GetMemoryRequirements(); 27 | var memoryAllocateInfo = new MemoryAllocateInfo( 28 | memReq.Size, 29 | deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0)); 30 | 31 | using (DeviceMemory memory = Device.AllocateMemory(memoryAllocateInfo)) 32 | { 33 | buffer.BindMemory(memory); 34 | 35 | var bufferViewCreateInfo = new BufferViewCreateInfo(Format.R32UInt); 36 | using (buffer.CreateView(bufferViewCreateInfo)) { } 37 | using (buffer.CreateView(bufferViewCreateInfo, CustomAllocator)) { } 38 | } 39 | } 40 | } 41 | 42 | public BufferTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 43 | 44 | private Buffer CreateBuffer() 45 | { 46 | var bufferCreateInfo = new BufferCreateInfo(DefaultBufferSize, BufferUsages.UniformTexelBuffer); 47 | return Device.CreateBuffer(bufferCreateInfo); 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Tests/Content/Shader.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 4 | 5 | layout(binding = 0, std430) buffer src_buffer 6 | { 7 | readonly int src_data[64]; 8 | }; 9 | 10 | layout(binding = 1, std430) buffer dst_buffer 11 | { 12 | int dst_data[64]; 13 | }; 14 | 15 | void main() 16 | { 17 | dst_data[gl_GlobalInvocationID.x] = src_data[gl_GlobalInvocationID.x]; 18 | } 19 | -------------------------------------------------------------------------------- /Tests/Content/Shader.comp.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Tests/Content/Shader.comp.spv -------------------------------------------------------------------------------- /Tests/Content/Shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec4 out_Color; 4 | 5 | void main() { 6 | out_Color = vec4(1.0, 0.68, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /Tests/Content/Shader.frag.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Tests/Content/Shader.frag.spv -------------------------------------------------------------------------------- /Tests/Content/Shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | out gl_PerVertex 4 | { 5 | vec4 gl_Position; 6 | }; 7 | 8 | void main() { 9 | vec2 pos[3] = vec2[3](vec2(-0.7, 0.7), vec2(0.7, 0.7), vec2(0.0, -0.7)); 10 | gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /Tests/Content/Shader.vert.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discosultan/VulkanCore/222d5d86322e2447bc0deb5d1c03da8b614eba91/Tests/Content/Shader.vert.spv -------------------------------------------------------------------------------- /Tests/DeviceMemoryTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class DeviceMemoryTest : HandleTestBase 8 | { 9 | [Fact] 10 | public void MapAndUnmapMemory() 11 | { 12 | const int allocationSize = 32; 13 | using (DeviceMemory memory = AllocateMappableMemory(allocationSize)) 14 | { 15 | memory.Map(0, allocationSize); 16 | memory.Unmap(); 17 | } 18 | } 19 | 20 | [Fact] 21 | public void GetCommitment() 22 | { 23 | const int allocationSize = 32; 24 | using (DeviceMemory memory = AllocateMappableMemory(allocationSize)) 25 | { 26 | long commitment = memory.GetCommitment(); 27 | Assert.True(commitment > 0); 28 | } 29 | } 30 | 31 | public DeviceMemoryTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) 32 | { 33 | DefaultPhysicalDevice = defaults.PhysicalDevice; 34 | DefaultDevice = defaults.Device; 35 | } 36 | 37 | private PhysicalDevice DefaultPhysicalDevice { get; } 38 | private Device DefaultDevice { get; } 39 | 40 | private DeviceMemory AllocateMappableMemory(int size) 41 | { 42 | PhysicalDeviceMemoryProperties memoryProperties = DefaultPhysicalDevice.GetMemoryProperties(); 43 | int memoryTypeIndex = memoryProperties.MemoryTypes.IndexOf(~0, MemoryProperties.HostVisible | MemoryProperties.HostCoherent); 44 | 45 | return DefaultDevice.AllocateMemory(new MemoryAllocateInfo(size, memoryTypeIndex)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/EventTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class EventTest : HandleTestBase 8 | { 9 | [Fact] 10 | public void SetEvent() 11 | { 12 | using (Event evt = Device.CreateEvent()) 13 | evt.Set(); 14 | } 15 | 16 | [Fact] 17 | public void ResetEvent() 18 | { 19 | using (Event evt = Device.CreateEvent()) 20 | evt.Reset(); 21 | } 22 | 23 | [Fact] 24 | public void GetEventStatus() 25 | { 26 | using (Event evt = Device.CreateEvent()) 27 | { 28 | Result status = evt.GetStatus(); 29 | Assert.Equal(Result.EventReset, status); 30 | 31 | evt.Set(); 32 | status = evt.GetStatus(); 33 | Assert.Equal(Result.EventSet, status); 34 | 35 | evt.Reset(); 36 | status = evt.GetStatus(); 37 | Assert.Equal(Result.EventReset, status); 38 | } 39 | } 40 | 41 | public EventTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/ExtentTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class ExtentTest 7 | { 8 | [Fact] 9 | public void Extent2DEquals() 10 | { 11 | var val1 = new Extent2D(0, 1); 12 | var val2 = new Extent2D(2, 3); 13 | 14 | Assert.True(val1.Equals(val1)); 15 | Assert.False(val1.Equals(val2)); 16 | Assert.True(val1 == val1); 17 | Assert.False(val1 == val2); 18 | Assert.False(val1 != val1); 19 | Assert.True(val1 != val2); 20 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 21 | } 22 | 23 | [Fact] 24 | public void Extent3DEquals() 25 | { 26 | var val1 = new Extent3D(0, 1, 2); 27 | var val2 = new Extent3D(3, 4, 5); 28 | 29 | Assert.True(val1.Equals(val1)); 30 | Assert.False(val1.Equals(val2)); 31 | Assert.True(val1 == val1); 32 | Assert.False(val1 == val2); 33 | Assert.False(val1 != val1); 34 | Assert.True(val1 != val2); 35 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/FenceTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class FenceTest : HandleTestBase 8 | { 9 | [Fact] 10 | public void WaitFence() 11 | { 12 | using (Fence fence = Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))) 13 | fence.Wait(); 14 | using (Fence fence = Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))) 15 | Device.WaitFences(new[] { fence }, true); 16 | } 17 | 18 | [Fact] 19 | public void ResetFence() 20 | { 21 | using (Fence fence = Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))) 22 | fence.Reset(); 23 | using (Fence fence = Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))) 24 | Device.ResetFences(fence); 25 | } 26 | 27 | [Fact] 28 | public void GetStatus() 29 | { 30 | using (Fence fence = Device.CreateFence(new FenceCreateInfo(FenceCreateFlags.Signaled))) 31 | { 32 | Result status = fence.GetStatus(); 33 | Assert.Equal(Result.Success, status); 34 | } 35 | } 36 | 37 | public FenceTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/ImageTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class ImageTest : HandleTestBase 8 | { 9 | private const int DefaultWidth = 32; 10 | private const int DefaultHeight = 32; 11 | private const int DefaultBytesPerPx = 4; 12 | 13 | [Fact] 14 | public void GetSubresourceLayout() 15 | { 16 | using (Image image = CreateImage(tiling: ImageTiling.Linear)) 17 | { 18 | SubresourceLayout layout = 19 | image.GetSubresourceLayout(new ImageSubresource(ImageAspects.Color, 0, 0)); 20 | Assert.Equal(DefaultWidth * DefaultHeight * DefaultBytesPerPx, layout.Size); 21 | } 22 | } 23 | 24 | [Fact] 25 | public void BindMemoryAndCreateView() 26 | { 27 | using (Image image = CreateImage()) 28 | { 29 | PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties(); 30 | MemoryRequirements memReq = image.GetMemoryRequirements(); 31 | 32 | using (DeviceMemory memory = Device.AllocateMemory(new MemoryAllocateInfo( 33 | memReq.Size, 34 | deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0)))) 35 | { 36 | image.BindMemory(memory); 37 | 38 | var createInfo = new ImageViewCreateInfo 39 | { 40 | Format = Format.B8G8R8A8UNorm, 41 | ViewType = ImageViewType.Image2D, 42 | SubresourceRange = new ImageSubresourceRange 43 | { 44 | AspectMask = ImageAspects.Color, 45 | LayerCount = 1, 46 | LevelCount = 1 47 | } 48 | }; 49 | using (image.CreateView(createInfo)) { } 50 | using (image.CreateView(createInfo, CustomAllocator)) { } 51 | } 52 | } 53 | } 54 | 55 | [Fact] 56 | public void GetSparseMemoryRequirements() 57 | { 58 | if (!PhysicalDeviceFeatures.SparseBinding || !PhysicalDeviceFeatures.SparseResidencyImage2D) return; 59 | 60 | using (Image image = CreateImage(ImageCreateFlags.SparseBinding | ImageCreateFlags.SparseResidency)) 61 | { 62 | SparseImageMemoryRequirements[] requirements = image.GetSparseMemoryRequirements(); 63 | Assert.True(requirements.Length > 0); 64 | } 65 | } 66 | 67 | 68 | public ImageTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 69 | 70 | private Image CreateImage(ImageCreateFlags flags = 0, ImageTiling tiling = ImageTiling.Optimal) 71 | { 72 | var createInfo = new ImageCreateInfo 73 | { 74 | ArrayLayers = 1, 75 | Extent = new Extent3D(DefaultWidth, DefaultHeight, 1), 76 | Format = Format.B8G8R8A8UNorm, 77 | ImageType = ImageType.Image2D, 78 | Usage = ImageUsages.TransferSrc | ImageUsages.Sampled, 79 | MipLevels = 1, 80 | Samples = SampleCounts.Count1, 81 | Flags = flags, 82 | Tiling = tiling 83 | }; 84 | return Device.CreateImage(createInfo); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Tests/Issues/KhxDeviceGroupCreationTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Xunit; 4 | using VulkanCore.Khx; 5 | 6 | namespace VulkanCore.Tests.Issues 7 | { 8 | // Many Vulkan extension commands were implemented as if they were statically exported. 9 | // That is only the case for certain WSI commands. 10 | // https://github.com/discosultan/VulkanCore/issues/8 11 | 12 | // The failure was discovered through vkEnumeratePhysicalDeviceGroupsKHX. 13 | // https://github.com/discosultan/VulkanCore/pull/9 14 | 15 | // There seems to be a bug in the validation layers as of 1.0.49. If validation layers are 16 | // enabled, vkEnumeratePhysicalDeviceGroupsKHX will raise an error when null is passed to 17 | // pPhysicalDeviceGroupProperties. 18 | 19 | public class KhxDeviceGroupCreationTest 20 | { 21 | [Fact] 22 | public void EnumeratePhysicalDeviceGroupsKhx() 23 | { 24 | // Only continue with the test if "VK_KHX_device_group_creation" extension is present. 25 | ExtensionProperties[] availableExtensions = Instance.EnumerateExtensionProperties(); 26 | if (!availableExtensions.Contains(Constant.InstanceExtension.KhxDeviceGroupCreation)) return; 27 | 28 | var instance = new Instance(new InstanceCreateInfo( 29 | enabledExtensionNames: new[] { Constant.InstanceExtension.KhxDeviceGroupCreation })); 30 | 31 | PhysicalDeviceGroupPropertiesKhx[] groups = instance.EnumeratePhysicalDeviceGroupsKhx(); 32 | 33 | Assert.True(0 < groups.Length && groups.Length <= Constant.MaxDeviceGroupSizeKhx); 34 | Assert.True(groups[0].PhysicalDevices.Length > 0); 35 | Assert.True(groups[0].PhysicalDevices.All(physicalDevice => physicalDevice.Handle != IntPtr.Zero)); 36 | } 37 | 38 | [Fact] 39 | public void CreateDeviceWithDeviceGroupInfo() 40 | { 41 | ExtensionProperties[] availableExtensions = Instance.EnumerateExtensionProperties(); 42 | if (!availableExtensions.Contains(Constant.InstanceExtension.KhxDeviceGroupCreation)) return; 43 | 44 | var instance = new Instance(new InstanceCreateInfo( 45 | enabledExtensionNames: new[] { Constant.InstanceExtension.KhxDeviceGroupCreation })); 46 | 47 | PhysicalDeviceGroupPropertiesKhx physicalDeviceGroup = instance.EnumeratePhysicalDeviceGroupsKhx()[0]; 48 | // We need a pointer to the array of native handles. 49 | IntPtr devicePtrs = Interop.Struct.AllocToPointer(physicalDeviceGroup.PhysicalDevices.ToHandleArray()); 50 | 51 | // Fill in the device group create info struct. 52 | var deviceGroupCreateInfo = new DeviceGroupDeviceCreateInfoKhx(physicalDeviceGroup.PhysicalDevices.Length, devicePtrs); 53 | // We also need a pointer to the create info struct itself. 54 | IntPtr createInfoPtr = Interop.Struct.AllocToPointer(ref deviceGroupCreateInfo); 55 | 56 | // Finally, pass the device group create info pointer to the `Next` chain of device create info. 57 | physicalDeviceGroup.PhysicalDevices[0].CreateDevice(new DeviceCreateInfo( 58 | new[] { new DeviceQueueCreateInfo(0, 1, 1.0f) }, 59 | next: createInfoPtr)); 60 | 61 | // Make sure to free unmanaged allocations. 62 | Interop.Free(createInfoPtr); 63 | Interop.Free(devicePtrs); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/OffsetTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class OffsetTest 7 | { 8 | [Fact] 9 | public void Offset2DEquals() 10 | { 11 | var val1 = new Offset2D(0, 1); 12 | var val2 = new Offset2D(2, 3); 13 | 14 | Assert.True(val1.Equals(val1)); 15 | Assert.False(val1.Equals(val2)); 16 | Assert.True(val1 == val1); 17 | Assert.False(val1 == val2); 18 | Assert.False(val1 != val1); 19 | Assert.True(val1 != val2); 20 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 21 | } 22 | 23 | [Fact] 24 | public void Offset3DEquals() 25 | { 26 | var val1 = new Offset3D(0, 1, 2); 27 | var val2 = new Offset3D(3, 4, 5); 28 | 29 | Assert.True(val1.Equals(val1)); 30 | Assert.False(val1.Equals(val2)); 31 | Assert.True(val1 == val1); 32 | Assert.False(val1 == val2); 33 | Assert.False(val1 != val1); 34 | Assert.True(val1 != val2); 35 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/PhysicalDeviceTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using VulkanCore.Tests.Utilities; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace VulkanCore.Tests 7 | { 8 | public class PhysicalDeviceTest : HandleTestBase 9 | { 10 | [Fact] 11 | public void GetProperties() 12 | { 13 | PhysicalDeviceProperties properties = PhysicalDevice.GetProperties(); 14 | Assert.True(properties.DeviceName.Length > 0); 15 | } 16 | 17 | [Fact] 18 | public void GetQueueFamilyProperties() 19 | { 20 | QueueFamilyProperties[] properties = PhysicalDevice.GetQueueFamilyProperties(); 21 | Assert.True(properties.Length > 0); 22 | } 23 | 24 | [Fact] 25 | public void GetMemoryProperties() 26 | { 27 | PhysicalDeviceMemoryProperties properties = PhysicalDevice.GetMemoryProperties(); 28 | Assert.True(properties.MemoryHeaps.Length > 0); 29 | Assert.True(properties.MemoryHeaps.All(x => x.Size > 0)); 30 | Assert.True(properties.MemoryTypes.Length > 0); 31 | Assert.True(properties.MemoryTypes.All(x => 32 | x.HeapIndex >= 0 && 33 | x.HeapIndex < properties.MemoryHeaps.Length)); 34 | } 35 | 36 | [Fact] 37 | public void GetFeatures() 38 | { 39 | PhysicalDevice.GetFeatures(); 40 | } 41 | 42 | [Fact] 43 | public void GetImageFormatFeatures() 44 | { 45 | PhysicalDevice.GetImageFormatProperties(Format.B8G8R8A8UNorm, ImageType.Image2D, 46 | ImageTiling.Optimal, ImageUsages.ColorAttachment); 47 | } 48 | 49 | [Fact] 50 | public void EnumerateExtensionProperties() 51 | { 52 | ExtensionProperties[] properties = PhysicalDevice.EnumerateExtensionProperties(); 53 | Assert.True(properties.Length > 0); 54 | } 55 | 56 | [Fact] 57 | public void EnumerateLayerProperties() 58 | { 59 | LayerProperties[] properties = PhysicalDevice.EnumerateLayerProperties(); 60 | Assert.True(properties.Length > 0); 61 | } 62 | 63 | [Fact] 64 | public void CreateDevice() 65 | { 66 | // Required in order to keep the validation layer happy :) 67 | PhysicalDevice.GetQueueFamilyProperties(); 68 | 69 | var createInfo = new DeviceCreateInfo(new[] 70 | { 71 | new DeviceQueueCreateInfo(0, 1, 1.0f) 72 | }); 73 | using (PhysicalDevice.CreateDevice(createInfo)) { } 74 | using (PhysicalDevice.CreateDevice(createInfo, CustomAllocator)) { } 75 | } 76 | 77 | [Fact] 78 | public void GetSparseImageFormatProperties() 79 | { 80 | PhysicalDevice.GetSparseImageFormatProperties( 81 | Format.B8G8R8A8UNorm, 82 | ImageType.Image2D, 83 | SampleCounts.Count1, 84 | ImageUsages.ColorAttachment, 85 | ImageTiling.Linear); 86 | } 87 | 88 | [Fact] 89 | public void GetFormatProperties() 90 | { 91 | PhysicalDevice.GetFormatProperties(Format.B8G8R8A8UNorm); 92 | } 93 | 94 | public PhysicalDeviceTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Tests/PipelineCacheTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using VulkanCore.Tests.Utilities; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace VulkanCore.Tests 7 | { 8 | public class PipelineCacheTest : HandleTestBase 9 | { 10 | [Fact] 11 | public void GetData() 12 | { 13 | var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo( 14 | new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1, ShaderStages.Compute), 15 | new DescriptorSetLayoutBinding(1, DescriptorType.StorageBuffer, 1, ShaderStages.Compute)); 16 | using (DescriptorSetLayout descriptorSetLayout = Device.CreateDescriptorSetLayout(descriptorSetLayoutCreateInfo)) 17 | using (PipelineLayout pipelineLayout = Device.CreatePipelineLayout(new PipelineLayoutCreateInfo(new[] { descriptorSetLayout }))) 18 | using (ShaderModule shader = Device.CreateShaderModule(new ShaderModuleCreateInfo(ReadAllBytes("Shader.comp.spv")))) 19 | { 20 | var pipelineCreateInfo = new ComputePipelineCreateInfo( 21 | new PipelineShaderStageCreateInfo(ShaderStages.Compute, shader, "main"), 22 | pipelineLayout); 23 | 24 | byte[] cacheBytes; 25 | 26 | // Populate cache. 27 | using (PipelineCache cache = Device.CreatePipelineCache()) 28 | { 29 | using (Device.CreateComputePipeline(pipelineCreateInfo, cache)) { } 30 | cacheBytes = cache.GetData(); 31 | } 32 | 33 | Assert.False(cacheBytes.All(x => x == 0)); 34 | 35 | // Recreate pipeline from cache. 36 | using (PipelineCache cache = Device.CreatePipelineCache(new PipelineCacheCreateInfo(cacheBytes))) 37 | { 38 | using (Device.CreateComputePipeline(pipelineCreateInfo, cache)) { } 39 | } 40 | } 41 | } 42 | 43 | [Fact] 44 | public void MergePipelines() 45 | { 46 | using (PipelineCache dstCache = Device.CreatePipelineCache()) 47 | using (PipelineCache srcCache = Device.CreatePipelineCache()) 48 | { 49 | dstCache.MergeCache(srcCache); 50 | dstCache.MergeCaches(srcCache); 51 | } 52 | } 53 | 54 | public PipelineCacheTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/QueryTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using VulkanCore.Tests.Utilities; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace VulkanCore.Tests 7 | { 8 | public unsafe class QueryTest : HandleTestBase 9 | { 10 | [Fact] 11 | public void GetResults() 12 | { 13 | using (var cmdPool = Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueue.FamilyIndex))) 14 | using (var cmdBuffer = cmdPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]) 15 | using (var queryPool = Device.CreateQueryPool(new QueryPoolCreateInfo(QueryType.Occlusion, 1))) 16 | { 17 | cmdBuffer.Begin(); 18 | cmdBuffer.CmdBeginQuery(queryPool, 0); 19 | cmdBuffer.CmdEndQuery(queryPool, 0); 20 | cmdBuffer.End(); 21 | 22 | GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer })); 23 | Device.WaitIdle(); 24 | 25 | const int size = 1024; 26 | byte* pointer = stackalloc byte[size]; 27 | queryPool.GetResults(0, 1, size, new IntPtr(pointer), size); 28 | } 29 | } 30 | 31 | public QueryTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/QueueTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using VulkanCore.Tests.Utilities; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace VulkanCore.Tests 7 | { 8 | public class QueueTest : HandleTestBase 9 | { 10 | [Fact] 11 | public void PropertiesSet() 12 | { 13 | QueueFamilyProperties[] props = PhysicalDevice.GetQueueFamilyProperties(); 14 | int queueFamilyIndex = props.Length - 1; 15 | int queueCount = props[props.Length - 1].QueueCount; 16 | int queueIndex = queueCount - 1; 17 | var deviceCreateInfo = new DeviceCreateInfo(new[] 18 | { 19 | new DeviceQueueCreateInfo(queueFamilyIndex, queueCount, Enumerable.Range(0, queueCount).Select(_ => 1.0f).ToArray()) 20 | }); 21 | using (Device device = PhysicalDevice.CreateDevice(deviceCreateInfo)) 22 | { 23 | Queue queue = device.GetQueue(queueFamilyIndex, queueIndex); 24 | 25 | Assert.Equal(device, queue.Parent); 26 | Assert.Equal(queueFamilyIndex, queue.FamilyIndex); 27 | Assert.Equal(queueIndex, queue.Index); 28 | } 29 | } 30 | 31 | [Fact] 32 | public void WaitIdle() 33 | { 34 | GraphicsQueue.WaitIdle(); 35 | } 36 | 37 | [Fact] 38 | public void Submit() 39 | { 40 | GraphicsQueue.Submit(null, 0, null, null); 41 | GraphicsQueue.Submit(new SubmitInfo()); 42 | GraphicsQueue.Submit(new[] { new SubmitInfo() }); 43 | } 44 | 45 | [Fact] 46 | public void BindSparse() 47 | { 48 | var bindSparseInfo = new BindSparseInfo(null, null, null, null, null); 49 | GraphicsQueue.BindSparse(bindSparseInfo); 50 | GraphicsQueue.BindSparse(new[] { bindSparseInfo }); 51 | } 52 | 53 | public QueueTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tests/RectTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class RectTest 7 | { 8 | [Fact] 9 | public void Rect2DEquals() 10 | { 11 | var val1 = new Rect2D(0, 1, 2, 3); 12 | var val2 = new Rect2D(4, 5, 6, 7); 13 | 14 | Assert.True(val1.Equals(val1)); 15 | Assert.False(val1.Equals(val2)); 16 | Assert.True(val1 == val1); 17 | Assert.False(val1 == val2); 18 | Assert.False(val1 != val1); 19 | Assert.True(val1 != val2); 20 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/RenderPassTest.cs: -------------------------------------------------------------------------------- 1 | using VulkanCore.Tests.Utilities; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace VulkanCore.Tests 6 | { 7 | public class RenderPassTest : HandleTestBase 8 | { 9 | [Fact] 10 | public void GetRenderAreaGranularity() 11 | { 12 | using (RenderPass renderPass = CreateRenderPass()) 13 | { 14 | Extent2D granularity = renderPass.GetRenderAreaGranularity(); 15 | Assert.True(granularity.Width > 0); 16 | Assert.True(granularity.Height > 0); 17 | } 18 | } 19 | 20 | [Fact] 21 | public void CreateFramebuffer() 22 | { 23 | var renderPassCreateInfo = new RenderPassCreateInfo( 24 | new[] { new SubpassDescription() } 25 | ); 26 | using (RenderPass renderPass = Device.CreateRenderPass(renderPassCreateInfo)) 27 | { 28 | var framebufferCreateInfo = new FramebufferCreateInfo(null, 2, 2); 29 | using (renderPass.CreateFramebuffer(framebufferCreateInfo)) { } 30 | using (renderPass.CreateFramebuffer(framebufferCreateInfo, CustomAllocator)) { } 31 | } 32 | } 33 | 34 | private RenderPass CreateRenderPass() 35 | { 36 | var attachments = new[] 37 | { 38 | new AttachmentDescription 39 | { 40 | Samples = SampleCounts.Count1, 41 | Format = Format.B8G8R8A8UNorm, 42 | InitialLayout = ImageLayout.PresentSrcKhr, 43 | FinalLayout = ImageLayout.PresentSrcKhr, 44 | LoadOp = AttachmentLoadOp.Clear, 45 | StoreOp = AttachmentStoreOp.Store, 46 | StencilLoadOp = AttachmentLoadOp.DontCare, 47 | StencilStoreOp = AttachmentStoreOp.DontCare 48 | } 49 | }; 50 | var subpasses = new[] 51 | { 52 | new SubpassDescription 53 | { 54 | ColorAttachments = new[] { new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal) } 55 | } 56 | }; 57 | 58 | var createInfo = new RenderPassCreateInfo(subpasses, attachments); 59 | return Device.CreateRenderPass(createInfo); 60 | } 61 | 62 | public RenderPassTest(DefaultHandles defaults, ITestOutputHelper output) : base(defaults, output) { } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Tests/SizeTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class SizeTest 7 | { 8 | [Fact] 9 | public void ImplicitConversions() 10 | { 11 | const int intVal = 1; 12 | const long longVal = 2; 13 | var intPtrVal = new IntPtr(3); 14 | 15 | Size intSize = intVal; 16 | Size longSize = longVal; 17 | Size intPtrSize = intPtrVal; 18 | 19 | Assert.Equal(intVal, (int)intSize); 20 | Assert.Equal(longVal, (long)longSize); 21 | Assert.Equal(intPtrVal, (IntPtr)intPtrSize); 22 | } 23 | 24 | [Fact] 25 | public void ConvertToString() 26 | { 27 | IntPtr intPtrVal = new IntPtr(1); 28 | Size sizeVal = intPtrVal; 29 | Assert.Equal(intPtrVal.ToString(), sizeVal.ToString()); 30 | } 31 | 32 | [Fact] 33 | public void SizeEquals() 34 | { 35 | var val1 = new Size(0); 36 | var val2 = new Size(1); 37 | 38 | Assert.True(val1.Equals(val1)); 39 | Assert.False(val1.Equals(val2)); 40 | Assert.True(val1 == val1); 41 | Assert.False(val1 == val2); 42 | Assert.False(val1 != val1); 43 | Assert.True(val1 != val2); 44 | Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); 45 | } 46 | 47 | [Fact] 48 | public void CompareTo() 49 | { 50 | var val1 = new Size(0); 51 | var val2 = new Size(1); 52 | 53 | Assert.Equal(-1, val1.CompareTo(val2)); 54 | Assert.Equal(0, val1.CompareTo(val1)); 55 | Assert.Equal(1, val2.CompareTo(val1)); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/Utilities/HandleTestBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | 8 | namespace VulkanCore.Tests.Utilities 9 | { 10 | public abstract class HandleTestBase : IClassFixture, IDisposable 11 | { 12 | // Since we are tracking memory allocations and allocations are notified 13 | // at a global level, we match the notification against the thread id this 14 | // test class was created on to only record allocations from this thread. 15 | private readonly Guid _threadId = Interop.ThreadId; 16 | private readonly HashSet _allocs = new HashSet(); 17 | private readonly DefaultHandles _defaults; 18 | 19 | protected HandleTestBase(DefaultHandles defaults, ITestOutputHelper output) 20 | { 21 | _defaults = defaults; 22 | 23 | Output = output; 24 | 25 | // Subscribe to track memory alloc/free ops. 26 | Interop.OnDebugAlloc += OnAlloc; 27 | Interop.OnDebugFree += OnFree; 28 | } 29 | 30 | protected ITestOutputHelper Output { get; } 31 | protected Instance Instance => _defaults.Instance; 32 | protected PhysicalDevice PhysicalDevice => _defaults.PhysicalDevice; 33 | protected Device Device => _defaults.Device; 34 | protected Queue GraphicsQueue => _defaults.GraphicsQueue; 35 | protected ExtensionProperties[] AvailableInstanceExtensions => _defaults.AvailableInstanceExtensions; 36 | protected ExtensionProperties[] AvailableDeviceExtensions => _defaults.AvailableDeviceExtensions; 37 | protected PhysicalDeviceFeatures PhysicalDeviceFeatures => _defaults.PhysicalDeviceFeatures; 38 | protected PhysicalDeviceMemoryProperties PhysicalDeviceMemoryProperties => _defaults.PhysicalDeviceMemoryProperties; 39 | 40 | public virtual void Dispose() 41 | { 42 | // Unsubscribe from tracking memory. 43 | Interop.OnDebugAlloc -= OnAlloc; 44 | Interop.OnDebugFree -= OnFree; 45 | 46 | // Fail the test if any allocation is not cleared up. 47 | if (_allocs.Count > 0) 48 | { 49 | string allocPtrs = string.Join(", ", 50 | _allocs.Select(ptr => ptr.ToInt64().ToString("X"))); 51 | Assert.True(false, $"There are {_allocs.Count} unfreed unmanaged allocations: {allocPtrs}."); 52 | } 53 | } 54 | 55 | protected static byte[] ReadAllBytes(string assetName) 56 | { 57 | using (var ms = new MemoryStream()) 58 | { 59 | var assembly = typeof(HandleTestBase).Assembly; 60 | string assemblyName = assembly.FullName.Substring(0, assembly.FullName.IndexOf(',')); 61 | string path = $"{assemblyName}.Content.{assetName}"; 62 | assembly.GetManifestResourceStream(path).CopyTo(ms); 63 | return ms.ToArray(); 64 | } 65 | } 66 | 67 | // Ignores alignment! 68 | protected static AllocationCallbacks? CustomAllocator => new AllocationCallbacks( 69 | alloc: (userData, size, alignment, scope) => Interop.Alloc(size), 70 | realloc: (userData, original, size, alignment, scope) => Interop.ReAlloc(original, size), 71 | free: (userData, memory) => Interop.Free(memory), 72 | internalAlloc: (userData, size, type, scope) => { }, 73 | internalFree: (userData, size, type, scope) => { }); 74 | 75 | private void OnAlloc(object sender, (Guid threadId, IntPtr ptr) val) 76 | { 77 | if (val.threadId == _threadId) 78 | { 79 | // Fail the test if duplicate alloc to same address. 80 | bool success = _allocs.Add(val.ptr); 81 | if (!success) 82 | Assert.True(false, $"Duplicate alloc at {val.ptr}."); 83 | } 84 | } 85 | 86 | private void OnFree(object sender, (Guid threadId, IntPtr ptr) val) 87 | { 88 | if (val.threadId == _threadId) 89 | { 90 | // Fail the test if duplicate freeing of same address. 91 | bool success = _allocs.Remove(val.ptr); 92 | if (!success) 93 | Assert.True(false, $"Duplicate free at {val.ptr}."); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Tests/UtilityTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace VulkanCore.Tests 5 | { 6 | public class UtilityTest 7 | { 8 | [Fact] 9 | public void IndexOfMemoryTypes() 10 | { 11 | MemoryType[] memTypes = 12 | { 13 | new MemoryType { HeapIndex = 0, PropertyFlags = MemoryProperties.HostVisible }, 14 | new MemoryType { HeapIndex = 1, PropertyFlags = MemoryProperties.HostVisible | MemoryProperties.HostCoherent }, 15 | new MemoryType { HeapIndex = 2, PropertyFlags = MemoryProperties.HostVisible | MemoryProperties.HostCoherent } 16 | }; 17 | const int availableMemoryTypeBits = 0b0101; 18 | 19 | int index = memTypes.IndexOf(availableMemoryTypeBits, MemoryProperties.HostVisible | MemoryProperties.HostCoherent); 20 | 21 | Assert.Equal(2, index); 22 | } 23 | 24 | [Fact] 25 | public void IndexOfMemoryTypesForNull() 26 | { 27 | Assert.Throws(() => ((MemoryType[])null).IndexOf(~0, 0)); 28 | } 29 | 30 | [Fact] 31 | public void LayerPropertiesContains() 32 | { 33 | LayerProperties[] layerProperties = 34 | { 35 | new LayerProperties { LayerName = "name1" }, 36 | new LayerProperties { LayerName = "name2" } 37 | }; 38 | 39 | Assert.True(layerProperties.Contains("name2")); 40 | Assert.False(layerProperties.Contains("name3")); 41 | } 42 | 43 | [Fact] 44 | public void NullLayerPropertiesContains() 45 | { 46 | Assert.Throws(() => ((LayerProperties[])null).Contains("name")); 47 | } 48 | 49 | [Fact] 50 | public void ExtensionPropertiesContains() 51 | { 52 | ExtensionProperties[] layerProperties = 53 | { 54 | new ExtensionProperties { ExtensionName = "name1" }, 55 | new ExtensionProperties { ExtensionName = "name2" } 56 | }; 57 | 58 | Assert.True(layerProperties.Contains("name2")); 59 | Assert.False(layerProperties.Contains("name3")); 60 | } 61 | 62 | [Fact] 63 | public void NullLExtensionPropertiesContains() 64 | { 65 | Assert.Throws(() => ((ExtensionProperties[])null).Contains("name")); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Tests/VersionTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace VulkanCore.Tests 4 | { 5 | public class VersionTest 6 | { 7 | [Theory] 8 | [InlineData(1, 0, 0)] 9 | [InlineData(0, 1, 0)] 10 | [InlineData(0, 0, 1)] 11 | [InlineData(1, 2, 3)] 12 | public void ComponentsMatch(int major, int minor, int patch) 13 | { 14 | var version = new Version(major, minor, patch); 15 | 16 | Assert.Equal(major, version.Major); 17 | Assert.Equal(minor, version.Minor); 18 | Assert.Equal(patch, version.Patch); 19 | } 20 | 21 | [Fact] 22 | public void Equal() 23 | { 24 | var version1 = new Version(1, 2, 3); 25 | var version2 = new Version(1, 2, 3); 26 | 27 | Assert.Equal(version1, version2); 28 | } 29 | 30 | [Fact] 31 | public void NotEqual() 32 | { 33 | var version1 = new Version(1, 2, 3); 34 | var version2 = new Version(3, 2, 1); 35 | 36 | Assert.NotEqual(version1, version2); 37 | } 38 | 39 | [Fact] 40 | public void CompareLessThan() 41 | { 42 | var version1 = new Version(1, 2, 3); 43 | var version2 = new Version(1, 2, 4); 44 | 45 | Assert.Equal(-1, version1.CompareTo(version2)); 46 | } 47 | 48 | [Fact] 49 | public void CompareEqual() 50 | { 51 | var version1 = new Version(1, 2, 3); 52 | var version2 = new Version(1, 2, 3); 53 | 54 | Assert.Equal(0, version1.CompareTo(version2)); 55 | } 56 | 57 | [Fact] 58 | public void CompareGreaterThan() 59 | { 60 | var version1 = new Version(1, 2, 3); 61 | var version2 = new Version(1, 2, 2); 62 | 63 | Assert.Equal(1, version1.CompareTo(version2)); 64 | } 65 | 66 | [Fact] 67 | public void Zero() 68 | { 69 | var version = Version.Zero; 70 | Assert.Equal(0, version.Major); 71 | Assert.Equal(0, version.Minor); 72 | Assert.Equal(0, version.Patch); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Tests/VulkanCore.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | True 6 | false 7 | $(NoWarn);CS1718 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------