{"id":18828534,"url":"https://github.com/tgsstdio/mg","last_synced_at":"2025-10-14T18:17:03.519Z","repository":{"id":94238545,"uuid":"68625893","full_name":"tgsstdio/Mg","owner":"tgsstdio","description":"C# Vulkan interface/polyfill for WINDOWS and MacOS","archived":false,"fork":false,"pushed_at":"2019-08-28T14:44:56.000Z","size":7079,"stargazers_count":21,"open_issues_count":4,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-01T19:31:30.911Z","etag":null,"topics":["cross-platform","metal","opengl","opentk","vulkan"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tgsstdio.png","metadata":{"files":{"readme":"README.MD","changelog":"CHANGELOG.txt","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-19T16:47:16.000Z","updated_at":"2024-01-24T09:11:41.000Z","dependencies_parsed_at":"2023-07-27T10:30:30.121Z","dependency_job_id":null,"html_url":"https://github.com/tgsstdio/Mg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tgsstdio/Mg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tgsstdio%2FMg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tgsstdio%2FMg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tgsstdio%2FMg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tgsstdio%2FMg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tgsstdio","download_url":"https://codeload.github.com/tgsstdio/Mg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tgsstdio%2FMg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020350,"owners_count":26086864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cross-platform","metal","opengl","opentk","vulkan"],"created_at":"2024-11-08T01:30:27.576Z","updated_at":"2025-10-14T18:17:03.504Z","avatar_url":"https://github.com/tgsstdio.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Magnesium\n\n\u003e C# Vulkan interface/polyfill for WINDOWS and MacOS\n\nQuick Links\n\n- [CHANGELOG](#changelog)\n- [NUGET PACKAGES](#nuget-packages)\n- [EXAMPLES](#examples)\n- [BUILD INSTRUCTIONS](#build-instructions)\n- [DESIGN DECISIONS](#design-decisions)\n- [LICENSE](#license)\n- [WHY?](#why?)\n- [CROSS PLATFORM DEV GUIDE](#cross-platform-dev-guide)\n- [PLATFORM SUMMARY](#platform-summary)\n- [IMPLEMENTATIONS TODOs](#implementations-todos)\n\n----------\n\n\n## CHANGELOG\n\nMagnesium and its implementations uses [Semantic Versioning v2.0.0](http://semver.org/) for versioning assemblies\n\n### Version 5.2.8 (full release)\nSHOULD BE LAST COMPATIBLE VERSION BEFORE INTERFACE CHANGE i.e. Mg 7.0.0\n - Magnesium v5.2.9 - 10 Oct 2017\n\t- New enum value MgDeviceExtensionOption.SWAPCHAIN_ONLY\n\t- MgDefaultGraphicsConfiguration uses MgDeviceExtensionOption.SWAPCHAIN_ONLY as its default option\n\t- MgDefaultGraphicsDevice will ignore user specified DepthFormat and use highest available version\n - Magnesium.OpenGL v6.1.4\n\t- Updated w.r.t Magnesium v5.2.9\n - Magnesium.OpenGL.DesktopGL v6.1.5\n\t- Updated w.r.t Magnesium v5.2.9\n\t- GL002 - Fixed LineStrip issue (missing enum in switch)\n - Magnesium.Vulkan v5.0.7\n\t- Updated w.r.t Magnesium v5.2.9\n - Magnesium.PresentationSurfaces.OpenTK v1.0.4\n\t- Updated w.r.t Magnesium v5.2.9\n - Magnesium.Ktx v1.0.4\n\t- Updated w.r.t Magnesium v5.2.9\n\n### Version 5.2.8-beta\n - Magnesium v5.2.8 - 2 Sep 2017\n\t- New enum value MgDeviceExtensionOption.SWAPCHAIN_ONLY\n\t- MgDefaultGraphicsConfiguration uses MgDeviceExtensionOption.SWAPCHAIN_ONLY as its default option\n\t- MgDefaultGraphicsDevice will ignore user specified DepthFormat and use highest available version\n - Magnesium.OpenGL v6.1.4 beta\n - Magnesium.OpenGL.DesktopGL v6.1.4 beta\n - Magnesium.Vulkan v5.0.7 beta\n - Magnesium.PresentationSurfaces.OpenTK v1.0.4 beta\n - Magnesium.Ktx v1.0.4 beta\n\t- Updated w.r.t Magnesium v5.2.7\n\n### Version 6.0.0\n - Magnesium.OpenGL v6.0.0 - 8 Feb 2017\n - Magnesium.OpenGL.DesktopGL v6.0.0 - 8 Feb 2017\n\t- w.r.t Magnesium v5.0.4\n\t- Implemented descriptor sets functionality\n\t- Implemented GLFullFence of IMgFence interface\n\t- Implemented CopyBuffers into CommandBuffers\n\n### Version 5.0.0\n - Removing descriptor pool from IMgQueueInfo.CreatePartition because MgDescriptorPools should be explicitly set based on usage\n - Added IMgGraphicsConfiguration/MgDefaultGraphicsConfiguration to process one IMgThreadPartition \n - Modify IMgPresentationSurface.Initialize method signature\n\t -  void Initialize(MgFormat format, uint width, uint height);\n - New assembly created Magnesium.PresentationSurfaces.OpenTK\n - (BUGFIX) Magnesium.Vulkan v5.0.2 - 9th Nov 2016\n\t- FIXED - CmdBindDescriptorSets to pass in null into dynamic offsets \n\t- FIXED - CreateGraphicsPipelines to accept array of dynamic states \n - Magnesium.Metal v5.0.0 - 9 Nov 2016\n \t- Updated w.r.t Magnesium v5.0.4 \t\n - Magnesium.Ktx v1.0.0 - 24 Dec 2016\n\t- Loads Khronos .ktx image files\n\t\t\n### Version 4.0.0\n - Moving all implementations under one roof/repository\n\t- Magnesium \n\t\t- interface only\n\t- Magnesium.Vulkan \n\t\t- Vulkan implementation from existing repository\n\t- Magnesium.OpenGL \n\t\t- partial implementation created for MonoGame\n\t- Magnesium.OpenGL.AndroidGL \n\t      - implementation created for MonoGame + OpenTK\n\t- Magnesium.OpenGL.DesktopGL \n\t\t- implementation created for MonoGame + OpenTK\n\t- Magnesium.Metal \n\t\t- implementation using Metal iOS API for MacOS and iOS\n\n### Version 3.0.0\n - Breaking changes from classes to interfaces due to Magnesium.Vulkan implementation \n\n### Version 2.0.0\n - Breaking changes to function\n\n### Version 1.0.0\n\n - Now using Semantic Versioning v2.0.0 (http://semver.org/)\n\n\n----------\n\n## NUGET PACKAGES\n\n| Interface / Implementation | Latest Version  | Description |\n|-----------|----------|-----------|\n| [Magnesium](https://www.nuget.org/packages/Magnesium/) | 5.2.8  | Core C# Vulkan interface with all applications should reference |\n| [Magnesium.Vulkan](https://www.nuget.org/packages/Magnesium.Vulkan/) | 5.0.7 | C# interface to Vulkan version 1.0.17 |\n| [Magnesium.Metal](https://www.nuget.org/packages/Magnesium.Metal/) | 5.0.0  |iOS polyfill for Magnesium for iOS devices using Apple's own Metal API |\n| [Magnesium.OpenGL](https://www.nuget.org/packages/Magnesium.OpenGL/) | 6.1.4  | OpenGL enumation/polyfill to replicate most of Vulkan entities and features |\n| [Magnesium.OpenGL.DesktopGL](https://www.nuget.org/packages/Magnesium.OpenGL.DesktopGL/) | 6.1.5  | OpenTK / OpenGL 4.5 implementation |\n| [Magnesium.PresentationSurfaces.OpenTK](https://www.nuget.org/packages/Magnesium.PresentationSurfaces.OpenTK/) | 1.0.4  | Contains OpenTK implementation of IMgPresentationSurface for Vulkan \u0026 DesktopGL |\n| [Magnesium.Ktx](https://www.nuget.org/packages/Magnesium.Ktx/) | 1.0.4 | Loads Khronos .ktx image files |\n\n-----------\n\n## BUILD INSTRUCTIONS \n\n\n 1. Change directory to the Build folder in the repository \n 2. Open ```Mg ALL BUILD.sln``` in Visual Studio or Xamarin Studio\n 3. Build all projects attached to this solution. The assemblies can be found in the bin/ \n \t- Magnesium\n\t- Magnesium.OpenGL\n\t- Magnesium.Vulkan\n\n-----------\n\n## EXAMPLES \n\t\nAll Magnesium demos can be found in the examples folder\n \n - InstanceDemo (Windows)\n \t- Console only Vulkan interface test\n - MetalSample (MacOS)\n \t- IOC library used - [SimpleInjector](https://simpleinjector.org/index.html)\n \t- Spinning cube translation of Metal cube demo\n - KtxReader (Cross-Platform)\n \t- Opens a .ktx for testing\n - TriangleDemo (Windows, OpenTK)\n\t- Shared application code running on Vulkan and OpenGL \n \t- IOC library used - [LightInject](http://www.lightinject.net/)\n\t- Simple Vulkan triangle demo based on [Sascha Willems](https://github.com/SaschaWillems)'s [triangle demo](https://github.com/SaschaWillems/Vulkan/blob/master/triangle/triangle.cpp)\n - TextureDemo (Windows, OpenTK)\n  \t- IOC library used - [DryIoc](https://bitbucket.org/dadhi/dryioc)\n \t- Opens a .ktx image file and display it on a plane. Code based on [Sascha Willems](https://github.com/SaschaWillems)'s [texture demo](https://github.com/SaschaWillems/Vulkan/blob/master/texture/texture.cpp)\n\n\t\n----------\n\n## DESIGN DECISIONS\n\n1. It is the responsibility of the programmer to clean up any unmanaged memory used by Mg objects themselves after use. \nAlmost Mg interfaces require explicit calls to its DestoryXXX methods (e.g. void vkDestroyInstance ) to dispose any memory associated to the objects.\n\n2. Magnesium does not SPECIFIC a shader language of choice, rather relying on the shader language available to the platform itself. \n\n3. To benefit more multi-threaded application use in Vulkan/Magnesium, it is recommended to restrict instances of command pools (i.e. IMgCommandPool) and descriptor pools (i.e. IMgDescriptorPool) to a single thread.\nFor example, in application that uses 2 thread, each thread would have its own descriptor pool(s) and command pool(s) and none of the instances should be shared between those threads.          \n\n4. (TODO) You will not directly modify/set for any indirect draw call buffer data as the structs used for indirect draws.\nTherefore a indirect interface class must be created act as a bridge to allow improve portability.   \n\t\n\t\n----------\n\n## LICENSE\n\nLicensed under MIT license\n\n----------\n\n## WHY?\n\nScenario 1: \nYou want to implement a cross-platform C#/.net 2D/3D application with  graphics API/library that uses modern high-performance features such as \n\n - compute shaders\n - tessellation shaders\n - immutable storage\n - compiled shader bytecode\n - constant buffers/shader storage buffer objects\n - upfront memory allocation\n - general purpose memory\n - multi-indirect instanced draws\n\nHowever, the choice of the graphics API is dependant on the platform itself.\n\n1. DirectX 11/12: Available for Windows 10 and Xbox. No support for MacOS or Linux (double check?).\n2. OpenGL and OpenGL ES: Available on all platforms.  Yet Mac devices are limited to OpenGL 4.1. \n3. [Vulkan](https://khronosgroup.com):  a next generation low level graphics library designed with respect to multi-threading devices. Now available on Windows, Android N devices and Linux. Unofficial MacOS driver support available via [MoltenVK]()\n4. Metal: Apple's own graphics rendering library that has modern features such as compute shaders.\n\nVulkan is *almost* the correct choice for a modern graphics library because there is native driver support for Windows, Linux and Android N platforms. \n\nSo Magnesium is primarily a C#/.net interface for Vulkan (for Windows). \n\nHowever, Vulkan itself is not available or arriving on a number of platforms (e.g Apple) and leaves a number of the devices  i.e. iPad, iPhone, pre Android-N devices and even HTML 5 browsers unsupported.\n\n**Here** is where Magnesium comes to the rescue; it is an interface of Vulkan.  We can use dependency injection (i.e. BYO C# IOC container not MEF) to load a polyfill instead into your applications if native Vulkan support is not available.\n\n| Interface | Platforms |\n|-----------|-----------|\n| Magnesium  | Core C# Vulkan interface with all applications should reference |\n| Magnesium.Vulkan | C# interface to Vulkan version 1.0.17 |\n| Magnesium.Metal | iOS polyfill for Magnesium for iOS devices using Apple's own Metal API |\n| Magnesium.OpenGL | OpenGL enumation/polyfill to replicate most of Vulkan entities and features |\n| Magnesium.OpenGL.DesktopGL | OpenTK / OpenGL 4.5 implementation |\n| Magnesium.OpenGL.AndroidGL | OpenTK / Xamarin Android / OpenGL ES 2.0, 3.0, 3.1 implementations |\n\nTo reach a wider number of platforms, all implementations have compiled as portable core library profile 111. Maybe moving to .NET standard 2.0 when released.\nTo reduce recompilation, Magnesium libraries are compiled with minimal preprocessor defines\n\n - Most debug assemblies only use DEBUG\n\nA exception is Magnesium.Metal which uses UNIFIED for both debug and release assemblies as Xamarin assemblies that are compiled with UNIFIED can be both for iOS and MacOS applications.\n\n----------\n\n## CROSS PLATFORM DEV GUIDE\n\n### IMgShaderModule \n\nMagnesium does not SPECIFIC a shader language of choice, rather relying on the shader language available to the platform itself.\n \nBy passing a System.IO.Stream handle contain some data and its length in bytes into IMgDevice.CreateShaderModule, Magnesium and its implementation can cater to any shader file type.  \n\n```C#\npublic class MgShaderModuleCreateInfo\n{\n\tpublic Stream Code { get; set; }\n\tpublic UIntPtr CodeSize { get; set; }\n}\n```\n\n| Platform | Description | File extension |\n|----------|-------------|----------------|\n| Magnesium.Vulkan | SPIRV bytecode code | |\n| Magnesium.OpenGL | GLSL source code | .glsl, .frag, .vert |\n| Magnesium.Metal  | Metal source code | .metal |\n\nOPENGL: Since METAL does not allow \"main\" as a function entrypoint in MgPipelineStageCreateInfo.Name,  \nOpenGL GLSL shaders should not include ```void main()``` function section in the source code. To work around GLSL inability to specify a shader name,\nthe Magnesium.OpenGL implementation will append the ```void main() { \u003cshader_name\u003e() }``` dynamically.   \n\n```C#\npublic class MgPipelineStageCreateInfo\n{\n\tpublic MgPipelineStageFlagBits Stage { get; set; }\n\tpublic string Name { get; set; }\t\n}\n\n```\n\nVULKAN: Since METAL does not allow *\"main\"* as a function entrypoint in MgPipelineStageCreateInfo.Name, please use another \nentrypoint other than *\"main\"*. See [SPIRVReplace](https://github.com/tgsstdio/SPIRVReplace) CLI to convert glsl to valid SPIRV bytecode on Windows. \n\nMETAL: final Position.y should be flipped in the vertex shader\n\nOPENGL: gl_Position.y should be flipped in the vertex shader \t\n\n```GLSL\n\tgl_Position = vec4(in_position.x, -in_position.y, 0, 1);\n```\n\n### Compute\n\nMETAL: compute pipelines need to specify the dimensions of the workgroup therefore you must specify ThreadsPerWorkgroup when calling IMgDevice.CreateComputePipelines.\n\n```C#\npublic class MgComputePipelineCreateInfo\n{\n\tpublic MgPipelineCreateFlagBits Flags { get; set; }\n\tpublic MgPipelineShaderStageCreateInfo Stage { get; set; }\n\tpublic IMgPipelineLayout Layout { get; set; }\n\t// REQUIRED FOR METAL\n\tpublic MgVec3Ui ThreadsPerWorkgroup { get; set;}\n\tpublic IMgPipeline BasePipelineHandle { get; set; }\n\tpublic Int32 BasePipelineIndex { get; set; }\n}\n``` \n\n\n### Descriptor Sets\n\nOPENGL: Only one of the descriptor sets can be bound.  \nMETAL: Only one of the descriptor sets can be bound. Internally, descriptor sets, vertex buffers, samplers and textures are combined together within the shaders.       \n\n----------\n\n## PLATFORM SUMMARY\n\n\n| Platform | API     | Availability | Caveats |\n|----------|---------|--------------|---------|\n| Windows  | Vulkan  |  Yes         | Driver support | \n|          | OpenGL  |  Yes         | Driver support |\n|          | DirectX |  Yes         |                |\n| Android  | Vulkan  |  Yes*        | Only for Android N devices and above |\n|          | OpenGL  |  Yes*        | Widespread OpenGL ES 2.0+ availability, Limited devices using OpenGL ES 3.0 or 3.1.               |\n| MacOS\t   | Vulkan  |  Yes*         | No for official Apple driver, potential emulation via MoltenVK |\n|          | OpenGL  | Yes          | Limited to OpenGL 4.1 |\n|          | Metal   | Yes          | Most iOS devices with El Capitan |\n| Linux  | Vulkan | Yes | Driver support, Specific windowing API  |\n|        | OpenGL | Yes | Driver support |\n| HTML 5 | Vulkan | No  | No direct support for Chrome, Safari or Firefox browsers  | \n|        | OpenGL | Yes | Widespread OpenGL ES 2.0+ availability, Limited devices using OpenGL ES 3.0 or 3.1 |\n\n\n----------\n\n## IMPLEMENTATIONS TODOs\n\n| Features | Magnesium.Vulkan | Magnesium.Metal | Magnesium.OpenGL.DesktopGL |\n|----------|------------------|-----------------|----------------------------|\n| Draw arrays  | Yes  |  Yes  | Yes  |\n| Draw indexed  | Yes | Yes | Yes |\n| Indirect draws  | Yes, partial | Yes, partial  | Yes, partial  |\n| Indirect draw indexed |  Yes, partial   | Yes, partial  | Yes, partial  |\n| Graphics Pipelines | Yes, Completed  | Yes, Completed | No |\n| Secondary Command Buffers  | Yes, Completed  | No | No |\n| Compute Pipelines | Yes, Completed  | Yes, Completed | No |\n| Query Pools  | Yes, Completed | No | No |\n| Pipeline caches  | Yes, Completed | No | No |\n| CmdUpdateDescriptorSets (Writes)  | Yes, Completed | Yes, Completed | No |\n| CmdUpdateDescriptorSets (Copies)  | Yes, Completed | No | No |\n| Subpasses  | Yes, Completed | Yes, Partial | No |\n| Framebuffers  | Yes, Completed | Yes, Partial | No |\n\n\u003e Written with [StackEdit](https://stackedit.io/) \u0026 Visual Studio Code\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftgsstdio%2Fmg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftgsstdio%2Fmg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftgsstdio%2Fmg/lists"}