facticiusvir / sharpvk Goto Github PK
View Code? Open in Web Editor NEWC# Bindings for the Vulkan API & SPIR-V
License: MIT License
C# Bindings for the Vulkan API & SPIR-V
License: MIT License
It generates:
var fieldPointer = new SharpVk.Multivendor.DebugUtilsLabel[(uint)(QueueLabelCount)];
Instead of:
var fieldPointer = new SharpVk.Multivendor.DebugUtilsLabel[(uint)(pointer->QueueLabelCount)];
The .gen
version of SharpVk.Instance.Create
has the following prototype:
public static unsafe SharpVk.Instance Create(CommandCache commandCache, ArrayProxy<string>? enabledLayerNames, ArrayProxy<string>? enabledExtensionNames, SharpVk.InstanceCreateFlags? flags = default(SharpVk.InstanceCreateFlags?), SharpVk.ApplicationInfo? applicationInfo = default(SharpVk.ApplicationInfo?), SharpVk.Multivendor.DebugReportCallbackCreateInfo? debugReportCallbackCreateInfoExt = null, SharpVk.Multivendor.ValidationFlags? validationFlagsExt = null, SharpVk.Multivendor.DebugUtilsMessengerCreateInfo? debugUtilsMessengerCreateInfoExt = null, SharpVk.AllocationCallbacks? allocator = default(SharpVk.AllocationCallbacks?))
But the .partial
version has:
public static unsafe SharpVk.Instance Create(ArrayProxy<string>? enabledLayerNames, ArrayProxy<string>? enabledExtensionNames, SharpVk.InstanceCreateFlags? flags = null, SharpVk.ApplicationInfo? applicationInfo = null, SharpVk.Multivendor.DebugReportCallbackCreateInfo? debugReportCallbackCreateInfoExt = null, SharpVk.Multivendor.ValidationFlags? validationFlagsExt = null, AllocationCallbacks? allocator = null)
I would expect the only difference to be the presence of CommandCache
, but the former also has:
SharpVk.Multivendor.DebugUtilsMessengerCreateInfo? debugUtilsMessengerCreateInfoExt = null
While the latter doesn't. This means you can't, using that factory, create an instance with the new debugging framework rather than then old one.
Struct-category types which are passed by reference currently wrap a pointer to an interop struct in unmanaged memory - this is over-complicated and prone to memory leaks. Switch the design to keep public API state in managed memory and have methods to marshal to/from interop structs when needed in native methods.
HelloTriangle(UWP) is missing "output"(0–extern) subpass dependency making swapchain image "available" for the presentation.
This is mainly an issue for DebugUtilsMessengerCallbackData
, which contains DebugUtilsObjectNameInfo[]
, and thus is transitively not unmarshalled for use in CreateDebugUtilsMessenger
, I'm currently doing this:
using System;
namespace SharpVk.Multivendor
{
public partial class DebugReportDelegate : IDisposable
{
private readonly SharpVk.Multivendor.DebugReportCallback callback_;
private readonly System.Runtime.InteropServices.GCHandle gch_;
internal DebugReportDelegate(System.Runtime.InteropServices.GCHandle gch, SharpVk.Multivendor.DebugReportCallback callback)
{
callback_ = callback;
gch_ = gch;
}
public void Dispose()
{
callback_.Dispose();
gch_.Free();
}
}
public interface IDebugReportDelegate
{
bool DebugReportDelegate(SharpVk.Multivendor.DebugReportFlags flags, SharpVk.Multivendor.DebugReportObjectType objectType, ulong @object, HostSize location, int messageCode, string pLayerPrefix, string pMessage);
}
public partial class DebugUtilsDelegate : IDisposable
{
private readonly SharpVk.Multivendor.DebugUtilsMessenger callback_;
private readonly System.Runtime.InteropServices.GCHandle gch_;
internal DebugUtilsDelegate(System.Runtime.InteropServices.GCHandle gch, SharpVk.Multivendor.DebugUtilsMessenger callback)
{
callback_ = callback;
gch_ = gch;
}
public void Dispose()
{
callback_.Dispose();
gch_.Free();
}
}
public interface IDebugUtilsDelegate
{
bool DebugUtilsDelegate(SharpVk.Multivendor.DebugUtilsMessageSeverityFlags messageSeverity, SharpVk.Multivendor.DebugUtilsMessageTypeFlags messageTypes, SharpVk.Multivendor.DebugUtilsMessengerCallbackData pCallbackDatas);
}
/// <summary>
///
/// </summary>
public static class HLInstanceExtensions
{
/// <summary>
/// Create a debug report callback object.
/// </summary>
/// <param name="extendedHandle">
/// The Instance handle to extend.
/// </param>
/// <param name="flags">
/// flags indicate which event(s) will cause this callback to be
/// called. Flags are interpreted as bitmasks and multiple may be set.
/// Bits which can be set include: + --
/// </param>
/// <param name="allocator">
/// An optional AllocationCallbacks instance that controls host memory
/// allocation.
/// </param>
public static SharpVk.Multivendor.DebugReportDelegate CreateDebugReportDelegate(this SharpVk.Instance extendedHandle, SharpVk.Multivendor.IDebugReportDelegate callback, SharpVk.Multivendor.DebugReportFlags? flags = default(SharpVk.Multivendor.DebugReportFlags?), SharpVk.AllocationCallbacks? allocator = default(SharpVk.AllocationCallbacks?))
{
System.Runtime.InteropServices.GCHandle gch = System.Runtime.InteropServices.GCHandle.Alloc(callback);
try
{
SharpVk.Multivendor.DebugReportCallback result = extendedHandle.CreateDebugReportCallback(DebugReportDelegate, flags, System.Runtime.InteropServices.GCHandle.ToIntPtr(gch), allocator);
return new SharpVk.Multivendor.DebugReportDelegate(gch, result);
}
catch
{
gch.Free();
throw;
}
}
private static readonly SharpVk.Multivendor.DebugReportCallbackDelegate DebugReportDelegate = DebugReport;
private static Bool32 DebugReport(SharpVk.Multivendor.DebugReportFlags flags, SharpVk.Multivendor.DebugReportObjectType objectType, ulong @object, HostSize location, int messageCode, string pLayerPrefix, string pMessage, IntPtr pUserData)
{
if (pUserData == IntPtr.Zero)
{
return false;
}
System.Runtime.InteropServices.GCHandle gch = System.Runtime.InteropServices.GCHandle.FromIntPtr(pUserData);
IDebugReportDelegate idrd = (IDebugReportDelegate)gch.Target;
if (idrd == null)
{
return false;
}
return idrd.DebugReportDelegate(flags, objectType, @object, location, messageCode, pLayerPrefix, pMessage);
}
/// <summary>
/// Create a debug utils messenger object.
/// </summary>
/// <param name="extendedHandle">
/// The Instance handle to extend.
/// </param>
/// <param name="flags">
/// flags indicate which event(s) will cause this callback to be
/// called. Flags are interpreted as bitmasks and multiple may be set.
/// Bits which can be set include: + --
/// </param>
/// <param name="allocator">
/// An optional AllocationCallbacks instance that controls host memory
/// allocation.
/// </param>
public static SharpVk.Multivendor.DebugUtilsDelegate CreateDebugUtilsDelegate(this SharpVk.Instance extendedHandle, SharpVk.Multivendor.DebugUtilsMessageSeverityFlags messageSeverity, SharpVk.Multivendor.DebugUtilsMessageTypeFlags messageType, SharpVk.Multivendor.IDebugUtilsDelegate callback, SharpVk.Multivendor.DebugUtilsMessengerCreateFlags? flags = default(SharpVk.Multivendor.DebugUtilsMessengerCreateFlags?), SharpVk.AllocationCallbacks? allocator = default(SharpVk.AllocationCallbacks?))
{
System.Runtime.InteropServices.GCHandle gch = System.Runtime.InteropServices.GCHandle.Alloc(callback);
try
{
SharpVk.Multivendor.DebugUtilsMessenger result = extendedHandle.CreateDebugUtilsMessenger(messageSeverity, messageType, DebugUtilsDelegate, flags, System.Runtime.InteropServices.GCHandle.ToIntPtr(gch), allocator);
return new SharpVk.Multivendor.DebugUtilsDelegate(gch, result);
}
catch
{
gch.Free();
throw;
}
}
private static readonly SharpVk.Multivendor.DebugUtilsMessengerCallbackDelegate DebugUtilsDelegate = DebugUtils;
private unsafe static SharpVk.Multivendor.DebugUtilsLabel MarshalFrom(SharpVk.Interop.Multivendor.DebugUtilsLabel* pointer)
{
SharpVk.Multivendor.DebugUtilsLabel result = default(SharpVk.Multivendor.DebugUtilsLabel);
result.LabelName = pointer->LabelName == null ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(new IntPtr(pointer->LabelName));
result.Color = (pointer->Color[0], pointer->Color[1], pointer->Color[2], pointer->Color[3]);
return result;
}
private unsafe static SharpVk.Multivendor.DebugUtilsObjectNameInfo MarshalFrom(SharpVk.Interop.Multivendor.DebugUtilsObjectNameInfo* pointer)
{
SharpVk.Multivendor.DebugUtilsObjectNameInfo result = default(SharpVk.Multivendor.DebugUtilsObjectNameInfo);
result.ObjectType = pointer->ObjectType;
result.ObjectHandle = pointer->ObjectHandle;
result.ObjectName = pointer->ObjectName == null ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(new IntPtr(pointer->ObjectName));
return result;
}
private unsafe static SharpVk.Multivendor.DebugUtilsMessengerCallbackData MarshalFrom(SharpVk.Interop.Multivendor.DebugUtilsMessengerCallbackData* pointer)
{
SharpVk.Multivendor.DebugUtilsMessengerCallbackData result = default(SharpVk.Multivendor.DebugUtilsMessengerCallbackData);
result.Flags = pointer->Flags;
result.MessageIdName = pointer->MessageIdName == null ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(new IntPtr(pointer->MessageIdName));
result.MessageIdNumber = pointer->MessageIdNumber;
result.Message = pointer->Message == null ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(new IntPtr(pointer->Message));
if (pointer->QueueLabels == null)
{
result.QueueLabels = null;
}
else
{
result.QueueLabels = new DebugUtilsLabel[pointer->QueueLabelCount];
for (int index = 0; index < (uint)(result.QueueLabels.Length); index++)
{
result.QueueLabels[index] = MarshalFrom(&pointer->QueueLabels[index]);
}
}
if (pointer->CommandBufLabels == null)
{
result.CommandBufLabels = null;
}
else
{
result.CommandBufLabels = new DebugUtilsLabel[pointer->CommandBufLabelCount];
for (int index = 0; index < (uint)(result.CommandBufLabels.Length); index++)
{
result.CommandBufLabels[index] = MarshalFrom(&pointer->CommandBufLabels[index]);
}
}
if (pointer->Objects == null)
{
result.Objects = null;
}
else
{
result.Objects = new DebugUtilsObjectNameInfo[pointer->ObjectCount];
for (int index = 0; index < (uint)(result.Objects.Length); index++)
{
result.Objects[index] = MarshalFrom(&pointer->Objects[index]);
}
}
return result;
}
private static unsafe Bool32 DebugUtils(SharpVk.Multivendor.DebugUtilsMessageSeverityFlags messageSeverity, SharpVk.Multivendor.DebugUtilsMessageTypeFlags messageTypes, IntPtr pCallbackData, IntPtr pUserData)
{
if (pUserData == IntPtr.Zero)
{
return false;
}
System.Runtime.InteropServices.GCHandle gch = System.Runtime.InteropServices.GCHandle.FromIntPtr(pUserData);
IDebugUtilsDelegate idrd = (IDebugUtilsDelegate)gch.Target;
if (idrd == null)
{
return false;
}
SharpVk.Multivendor.DebugUtilsMessengerCallbackData userData = MarshalFrom((SharpVk.Interop.Multivendor.DebugUtilsMessengerCallbackData*)pCallbackData.ToPointer());
return idrd.DebugUtilsDelegate(messageSeverity, messageTypes, userData);
}
}
}
I tried to match the generated code style as much as possible, but without being able to use any of the internal HeapUtil
methods.
GetEventStatus, GetFenceStatus & WaitForFence return result as non-error VkResult codes - these need handling and returning
DeviceMemory.MapMemory has ref IntPtr data
, this seems more appropriate to be either an out
parameter or a return value.
e.g. LayerProperties.LayerName is a fixed-length char array, using a defined constant as the length.
As mentioned in #12, Shanq should be able to output SPIR-V for a compute pipeline.
Depends on the sample porting work in FacticiusVir/SharpVk-Samples#2
First of all, great job with SharpVk! So far it seems to provide the most pleasant C# Vulkan API to work with and it's nice to have a Windows sample working out of the box.
I noticed SharpVk has a dependency to GlmSharp. Is this something that is set-in-stone or are there any future plans on this matter?
Here are my thoughts:
Output SPIR-V binary files for Vertex & Fragment shaders compiled from LINQ expressions for simple struct-to-struct mappings.
Interop structs require a clean-up method to recursively free pointer-linked resources after Vulkan API calls complete.
I got the following warning from Vulkan:
ParameterValidation: vkCreateGraphicsPipelines: value of pCreateInfos[0].pStages[1].pNext must be NULL. This warning is based on the Valid Usage documentation for version 30 of the Vulkan header. It is possible that you are using a struct from a private extension or an extension that was added to a later version of the Vulkan header, in which case your use of pCreateInfos[0].pStages[1].pNext is perfectly valid but is not guaranteed to work correctly with validation enabled
Looking through your code, I saw that you did not explicitly set the Next field when you marshaled the structures. I fixed the warning by adding
pointer->Next = null;
to PipelineShaderStageCreateInfo.MarshalTo to fix the issue I was having.
I think even tough GLFW is here used for Vulkan that it would be nice to complete it.
For example I'm using it for Vulkan and would like to use it for OpenGL too. However in the current state this wouldn't be possible.
I'll extend the glfw3.cs file to be capable of using OpenGL too.
-EDIT-
I also would suggest to integrate this existing library (which is maybe outdated).
It's licensed under MIT too:
https://github.com/lodicolo/glfw-net/tree/master/glfw-net
I've believe I've found the source of the problem at
SharpVk/src/SharpVk/ImageBlit.gen.cs
Line 77 in 73ede85
While writing an app I got this error;
[Warning] vkCmdBlitImage: pRegions[0].srcOffsets specify a zero-volume area.
[Warning] vkCmdBlitImage: pRegions[0].dstOffsets specify a zero-volume area.
[Error] vkCmdBlitImage: region [0], source image of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D with srcOffset[].z values of (0, 0). These must be (0, 1).
The spec valid usage text states 'If the calling command's srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.'
(https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkImageBlit-srcImage-00247)
[Error] vkCmdBlitImage: region [0], dest image of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D with dstOffset[].z values of (0, 0). These must be (0, 1).
The spec valid usage text states 'If the calling command's dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.'
(https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkImageBlit-dstImage-00252)
Using the debugger I have determined that this is not in fact true, as the values are {{0, 0, 0}, {401, 377, 1}}
and {{0, 0, 0}, {401, 377, 1}}
respectively.
Perhaps I am misinterpreting things, but the code at
SharpVk/src/SharpVk/ImageBlit.gen.cs
Line 77 in 73ede85
It seems to be impossible to use vkDebugMarkerSetObjectNameEXT
. The info-struct expects the handle to the object casted to an uint64_t
. This does not seem to be possible with SharpVk, because the library never exposes the raw handles. See at the bottom of this bug report for the XML definition.
I suggest to expose the raw handles to all Vulkan resources via a property, for example RawHandle
. This is not a very elegant solution for this problem, but I think the raw handles should be exposed anyway, in case someone has to interact with native code or manually loaded extensions.
If you want to I can take a look at this and provide a pull request.
https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/vk.xml#L1686
<type category="struct" name="VkDebugMarkerObjectNameInfoEXT">
<member values="VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
<member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
<member><type>VkDebugReportObjectTypeEXT</type> <name>objectType</name></member> <!-- The type of the object -->
<member><type>uint64_t</type> <name>object</name></member> <!-- The handle of the object, cast to uint64_t -->
<member len="null-terminated">const <type>char</type>* <name>pObjectName</name></member> <!-- Name to apply to the object -->
</type>
Public methods on Handles currently use the default JoinNameParts logic (e.g. VkCreateInstance -> Instance.CreateInstance); instead, method name formatting should skip the containing Handle name where present (e.g. Instance.Create).
There's no marshal step from the fixed-length public to interop fields generated for input structures; as these are all 2-4 items in length, it may be worth revisiting generic Vector types instead of array-to-fixed-buffer marshalling.
After updating my version of sharpvk I found a whole bunch of new function overloads that include 'CommandCaches' as arguments, a quick look at the object browser and source would seem to indicate that it is an internal object used to store vulkan commands, and that it cannot be created by external code.
ex. public static ExtensionProperties[] EnumerateExtensionProperties(CommandCache commandCache, string layerName)
Is CommandCache meant to be visible from calling code? If so, it needs some work, as there doesn't currently seem to be any way to create or even acquire one. If not, the functions that include it should probably be set to internal, or otherwise hidden to avoid confusion.
vkEnumerateDeviceExtensionProperties
is in this library as PhysicalDevice.EnumerateDeviceExtensionProperties
, duplicating the term Device
. However, vkEnumerateInstanceExtensionProperties
is Instance.EnumerateExtensionProperties
, the second Instance
has been dropped. Same for Enumerate(Thing)LayerProperties
.
I tried other Vulkan c# at github, SharpVK is the only one that make the sample run in windows 10
Request for an UWP app sample :-)
Output from the validation layers suggests that one of the MemUtil WriteToPointer methods is mangling data when run on Linux; if the implementation of TypedReference is different on Mono this may be the cause. Portable library targets are also missing a set of the dynamic method & reflection functions used by current marshalling code, so these need rewritten.
With Patch 26, the individual man pages stored at https://github.com/KhronosGroup/Vulkan-Docs/tree/1.0/doc/specs/vulkan/man have been removed - a replacement needs to be generated from the source at https://github.com/KhronosGroup/Vulkan-Docs/tree/1.0/doc/specs/vulkan/chapters and integrated into the generator.
The len attribute of member fields can be used to translate pointers in Interop struct members or command parameters into arrays or null-terminated strings.
When calling the CreateDebugReportCallback I get
"System.ArgumentNullException: Value cannot be null. Parameter name: ptr
I am following the Vulkan Tutorial and using the samples as a guide. I am also using GLFW.NET instead of the built in GLFW.
Here is my full code: https://pastecode.xyz/view/92db0418
SOLVED:
In the Vulkan Tutorial I was following the debug callback extension used was "VK_EXT_debug_utils" switching it to "VK_EXT_debug_report" as the samples use fixed the issue.
These commands are successfully generated but need exercising in sample code:
I've found a rather odd bug in which the delegate used for DebugReportCallback is garbage collected, thus causing a random crash when the native handler calls it during the next vulkan call.
Fortunately, I believe this should be easily fixed by simply adding the delegate as a member to DebugReportCallback
My temporary solution was to simply preserve the delegate by keeping a reference to it bound to my window. It works well enough.
Hi, is possible to add support for Portable class library support, similar to Mono VulkanSharp, otherwise I wont be able to compile it under Android.
I have some performance improvments:
The function GetDelegateForFunctionPointer
is really slow compared to a PInvoke or a Calli instruction injection into the IL .dll.
public static unsafe void Variant(Int32 id, Int16* addr)
{
Silk.Cil.Ldarg(0);
Silk.Cil.Ldarg(1);
Silk.Cil.Load(EntryPoints);
Silk.Cil.Ldc_I4(2366);
Silk.Cil.Ldelem_I();
Silk.Cil.Calli(System.Runtime.InteropServices.CallingConvention.StdCall, typeof(void), typeof(UInt32), typeof(Int16*));
Silk.Cil.Ret();
}
In OpenTK there is an il rewriter (example above). It injects the calli instruction into the IL. A similiar Approach was done in SharpDx.
There is also a proposal dotnet/roslyn#11475
SuppressUnmanagedCodeSecurity
Attribute for pinvokeUse the SuppressUnmanagedCodeSecurity
Attribute for Releases increases the performance and should be not a problem in the use case.
Hi,
during my work with SharpVK I noticed that I need to apply every time casts to my bool values etc.
Instead of conversions I would like to see additional static members e.g.
partial class Bool32 {
public static bool True = Bool32(true);
public static bool False = Bool32(false);
}
Instance.EnumerateExtensionProperties
and PhysicalDevice.EnumerateDeviceExtensionProperties
take an optional pLayerName
, but there's no default null
on the parameter:
public unsafe SharpVk.ExtensionProperties[] EnumerateDeviceExtensionProperties(string layerName)
Am gonna move it here to clean StackOverflow comments.
In the HelloTriangle (UWP version at least) the presentQueue
is unused. The graphicsQueue
is used instead.
May it would be good to get a "real" object or null instead of the ulong @object.
Is this possible?
public unsafe delegate Bool32 DebugReportCallbackDelegate(DebugReportFlags flags, ortObjectType objectType, ulong @object, Size location, int messageCode, string layerPrefix, string message, IntPtr userData);
Without any exception? On 2nd frame... how to increase error detection?
Pls help, I actually cant trace the problem with the tools I have available. I keep getting a segmentation fault on Device.CreateRenderPass()
. I can send you a code sample of how I am using it if needed. It worked earlier, idk why its doing this.
The current SharpVk NuGet package framework is .Net4.6, but it should be compatible with earlier framework versions.
As in the title, I was looking into using Shanq (It's pretty cool) but I don't like the fact that I'm essentially locked into using glmSharp, I am asking this as I would perfer to be able to use the System.Numerics.Vector library instead, as it is built into windows and mono and has hardware/non-hardware acceleration built into it. It can be used in Vulkan as shown by plenty of other librarys, will System.Numerics vectors see any support?
When submitting the Vulkan API & SharpVK version values to Instance.Create, the Version object must be constructed and updated manually. API version is available in the Spec macros, and SharpVK version can be calculated from the current assembly file version.
In swapchain creation the imageCount
variable is not used. Instead literal 2
is used.
https://github.com/FacticiusVir/SharpVk/blob/master/SharpVk/SharpVk/CommandBuffer.cs#L490-L492
var arrayValue = offsets.GetArrayValue();
offsetsHandle = GCHandle.Alloc(arrayValue.Array);
marshalledOffsets = (DeviceSize*)(offsetsHandle.AddrOfPinnedObject() + (int)(MemUtil.SizeOf<DeviceSize>() * arrayValue.Offset)).ToPointer();
Maybe I don't understand something, but here not pinned GCHandle calls AddOfPinnedObject() and I have exception throwing on that line.
With this its working fine
GCHandle.Alloc(arrayValue.Array, GCHandleType.Pinned);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.