jwollen / sharpvulkan Goto Github PK
View Code? Open in Web Editor NEWC# bindings for https://www.khronos.org/vulkan/
License: MIT License
C# bindings for https://www.khronos.org/vulkan/
License: MIT License
Hi, I want to obtain a Bitmap from Vulkan, I have created a renderless implementation of the Vulkan rendering and I want to obtain an Image to display the results in the screen, but I'm unable to obtain the image byte data. My Draw function is the following one:
protected virtual unsafe void Draw() { var semaphoreCreateInfo = new SemaphoreCreateInfo { StructureType = StructureType.SemaphoreCreateInfo }; var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);
try
{
// Get the index of the next available swapchain image
currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
}
catch (SharpVulkanException e) when (e.Result == Result.ErrorOutOfDate)
{
// TODO: Handle resize and retry draw
throw new NotImplementedException();
}
// Record drawing command buffer
var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
commandBuffer.Begin(ref beginInfo);
DrawInternal();
commandBuffer.End();
// Submit
var drawCommandBuffer = commandBuffer;
var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
var submitInfo = new SubmitInfo
{
StructureType = StructureType.SubmitInfo,
WaitSemaphoreCount = 1,
WaitSemaphores = new IntPtr(&presentCompleteSemaphore),
WaitDstStageMask = new IntPtr(&pipelineStageFlags),
CommandBufferCount = 1,
CommandBuffers = new IntPtr(&drawCommandBuffer),
};
queue.Submit(1, &submitInfo, Fence.Null);
// Present
var swapchain = this.swapchain;
var currentBackBufferIndexCopy = currentBackBufferIndex;
var presentInfo = new PresentInfo
{
StructureType = StructureType.PresentInfo,
SwapchainCount = 1,
Swapchains = new IntPtr(&swapchain),
ImageIndices = new IntPtr(¤tBackBufferIndexCopy)
};
queue.Present(ref presentInfo);
// Wait
queue.WaitIdle();
device.ResetDescriptorPool(descriptorPool, DescriptorPoolResetFlags.None);
// Cleanup
device.DestroySemaphore(presentCompleteSemaphore);
}
private void DrawInternal()
{
// Update descriptors
var descriptorSets = stackalloc DescriptorSet[2];
var setLayouts = stackalloc DescriptorSetLayout[2];
setLayouts[0] = setLayouts[1] = descriptorSetLayout;
var allocateInfo = new DescriptorSetAllocateInfo
{
StructureType = StructureType.DescriptorSetAllocateInfo,
DescriptorPool = descriptorPool,
DescriptorSetCount = 2,
SetLayouts = new IntPtr(setLayouts),
};
device.AllocateDescriptorSets(ref allocateInfo, descriptorSets);
var bufferInfo = new DescriptorBufferInfo
{
Buffer = uniformBuffer,
Range = Vulkan.WholeSize
};
var write = new WriteDescriptorSet
{
StructureType = StructureType.WriteDescriptorSet,
DescriptorCount = 1,
DestinationSet = descriptorSets[0],
DestinationBinding = 0,
DescriptorType = DescriptorType.UniformBuffer,
BufferInfo = new IntPtr(&bufferInfo)
};
var copy = new CopyDescriptorSet
{
StructureType = StructureType.CopyDescriptorSet,
DescriptorCount = 1,
SourceBinding = 0,
DestinationBinding = 0,
SourceSet = descriptorSets[0],
DestinationSet = descriptorSets[1]
};
device.UpdateDescriptorSets(1, &write, 0, null);
device.UpdateDescriptorSets(0, null, 1, ©);
// Post-present transition
var memoryBarrier = new ImageMemoryBarrier
{
StructureType = StructureType.ImageMemoryBarrier,
Image = backBuffers[currentBackBufferIndex],
SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
OldLayout = ImageLayout.PresentSource,
NewLayout = ImageLayout.ColorAttachmentOptimal,
SourceAccessMask = AccessFlags.MemoryRead,
DestinationAccessMask = AccessFlags.ColorAttachmentWrite
};
commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
// Clear render target
var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);
commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(0, 0, 0, 1), 1, &clearRange);
// Begin render pass
var renderPassBeginInfo = new RenderPassBeginInfo
{
StructureType = StructureType.RenderPassBeginInfo,
RenderPass = renderPass,
Framebuffer = framebuffers[currentBackBufferIndex],
RenderArea = new Rect2D(0, 0, (uint)ActualWidth, (uint)ActualHeight),
};
commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline);
// Bind pipeline
commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);
// Bind descriptor sets
commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, 1, descriptorSets + 1, 0, null);
// Set viewport and scissor
var viewport = new Viewport(0, 0, (float)ActualWidth, (float)ActualHeight);
commandBuffer.SetViewport(0, 1, &viewport);
var scissor = new Rect2D(0, 0, (uint)ActualWidth, (uint)ActualHeight);
commandBuffer.SetScissor(0, 1, &scissor);
// Bind vertex buffer
var vertexBufferCopy = vertexBuffer;
ulong offset = 0;
commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset);
// Draw vertices
commandBuffer.Draw(3, 1, 0, 0);
// End render pass
commandBuffer.EndRenderPass();
// Pre-present transition
memoryBarrier = new ImageMemoryBarrier
{
StructureType = StructureType.ImageMemoryBarrier,
Image = backBuffers[currentBackBufferIndex],
SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
OldLayout = ImageLayout.ColorAttachmentOptimal,
NewLayout = ImageLayout.PresentSource,
SourceAccessMask = AccessFlags.ColorAttachmentWrite,
DestinationAccessMask = AccessFlags.MemoryRead
};
commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
}
Hi, I would like to say thank you for what are you doing and providing the Sharp library.
I have a question, is it possible to use Vulkan without any external Api like SharpDX or OpenGl?
Hi,
I was trying to implement Vulkan support but at the moment mono SharpVulkan is not complete, do you plan to proceed with binding? Can you release the binding generation tool?
Not really an issue, but rather something to help @jwollen a bit:
There is another C# Vulkan binding out there: https://github.com/mono/VulkanSharp
Apparently, it's generator is open source as well! :D You might be able to incorporate parts of it into your code (though, that is a lot of work and usually only worth it, if there is an issue that you can't figure out how to solve)
Amazing project! I tried to get this to work in C# ( https://gist.github.com/graphitemaster/e162a24e57379af840d4 ) but this line:instance = Vulkan.CreateInstance(ref instanceInfo);
doesn't work as intended. It says that vkCreateInstance(__createInfo__, allocator, &instance).CheckError();
unbalanced the stack. (Should I post a screenshot?)
Here is my code:
using System;
using System.Runtime.InteropServices;
namespace SharpVulkan
{
class Program
{
unsafe public static void Main(string[] args)
{
//also, you need to make sure to free the unmanaged memory:
//Marshal.FreeHGlobal(strPtr);
//Constants
IntPtr NULL = IntPtr.Zero;
ApplicationInfo applicationInfo = new ApplicationInfo();
InstanceCreateInfo instanceInfo = new InstanceCreateInfo();
Instance instance;
// Filling out application description:
// sType is mandatory
applicationInfo.StructureType = StructureType.ApplicationInfo;
// pNext is mandatory
applicationInfo.Next = NULL;
// The name of our application
applicationInfo.ApplicationName = Marshal.StringToHGlobalUni("Tutorial 1");
// The name of the engine (e.g: Game engine name)
applicationInfo.EngineName = NULL;
// The version of the engine
applicationInfo.EngineVersion = 1;
// The version of Vulkan we're using for this application
applicationInfo.ApiVersion = Vulkan.ApiVersion;
// Filling out instance description:
// sType is mandatory
instanceInfo.StructureType = StructureType.InstanceCreateInfo; // VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
// pNext is mandatory
instanceInfo.Next = NULL;
// flags is mandatory
instanceInfo.Flags = 0;
// The application info structure is then passed through the instance
// object to IntPtr (before calling WinApi):
GCHandle handle1 = GCHandle.Alloc(applicationInfo);
IntPtr parameter = (IntPtr)handle1;
// call WinAPi and pass the parameter here
//IntPtr x = NULL;
//Marshal.StructureToPtr(applicationInfo, x, true); // &applicationInfo;
instanceInfo.ApplicationInfo = parameter;
// Don't enable and layer
instanceInfo.EnabledLayerCount = 0;
instanceInfo.EnabledLayerNames = NULL;
// Don't enable any extensions
instanceInfo.EnabledExtensionCount = 0;
instanceInfo.EnabledExtensionNames = NULL;
// Now create the desired instance
instance = Vulkan.CreateInstance(ref instanceInfo);
// To Come Later
// ...
// ...
// Never forget to free resources
instance.Destroy();
}
}
}```
Also, an example would be awesome!
Hello, I have tried to make some tests similar to your sample MiTri and I wanted to create some polygon primitives, e.g rectangle. I have tried to make a vertex array like :
var vertices = new[,]
{
{ -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f }, // Top-Left
{ 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }, // Top-right
{ 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, // Bottom-right
{ -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f }, // Bottom-left
};
and in line setted to 4
// Draw vertices
commandBuffer.Draw(4, 1, 0, 0);
But it still draws triangle. How can I play with vertexes to draw different shapes?
Thank you in advance
Hey @jwollen , first of all just wanted to say thanks for open-sourcing this. I'm trying to get into Vulkan and this looks like a well-designed wrapper from what (very) little I've managed to do so far
I had a couple questions:
SharpVulkan.dll!SharpVulkan.ResultExtensions.CheckError(SharpVulkan.Result result) Line 29 C#
SharpVulkan.dll!SharpVulkan.Device.CreateGraphicsPipelines(SharpVulkan.PipelineCache pipelineCache, uint createInfoCount, SharpVulkan.GraphicsPipelineCreateInfo* createInfos, SharpVulkan.AllocationCallbacks* allocator) Line 876 C#
MiniTri.exe!MiniTri.Sample.CreatePipeline() Line 600 C#
MiniTri.exe!MiniTri.Sample.Initialize() Line 96 C#
MiniTri.exe!MiniTri.Sample.Run() Line 79 C#
MiniTri.exe!MiniTri.Program.Main() Line 32 C#
Vulkan reports:
Error: Attempt to set lineWidth to 0.000000 but physical device wideLines feature not supported/enabled so lineWidth must be 1.0f! ([10] DS)
Warning: vkCreateGraphicsPipelines: returned VK_ERROR_VALIDATION_FAILED_EXT, indicating that API validation has detected an invalid use of the API ([1] ParameterValidation)
First of all, I have 2 graphics card (Intel and Nvidia) and can run the Vulkan Demos without a problem, if I start them with my Nvidia Graphics card (Lunar SDK? Or some other demos..)
(I think I have the 1.0.5 version of Vulkan)
Upon starting your Sample, it throws an error: ErrorIncompatibleDriver
Call Stack:
> SharpVulkan.dll!SharpVulkan.ResultExtensions.CheckError(SharpVulkan.Result result) Line 29
SharpVulkan.dll!SharpVulkan.Vulkan.CreateInstance(ref SharpVulkan.InstanceCreateInfo createInfo, SharpVulkan.AllocationCallbacks* allocator) Line 15
MiniTri.exe!MiniTri.Sample.CreateInstance() Line 140
MiniTri.exe!MiniTri.Sample.Initialize() Line 85
MiniTri.exe!MiniTri.Sample.Run() Line 79
MiniTri.exe!MiniTri.Program.Main() Line 32
If I take out the line that throws the error, I get this error:
An unhandled exception of type 'System.AccessViolationException' occurred in SharpVulkan.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
It happens here: physicalDevice = instance.PhysicalDevices[1];
Hi jwollen,
First of all thank you very much for your excellent work exposing Vulkan to .NET!
I started using it in my test project and while trying to add textures spotted a bug in generated code for PhysicalDevice.GetFormatProperties(). I believe the second parameter should be with out signature.
I can send you a patch for Functions.cs but since it is generated you probably better fix the template.
Best Regards,
Boris.
See also KhronosGroup/Vulkan-Docs#814
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.