mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.17k stars 522 forks source link

Vulkan GPU backend #252

Closed jcoder58 closed 4 years ago

jcoder58 commented 7 years ago

Does SkiaSharp support the Vulkan GPU Backend? If not, any plans to add it? I'm working on a Vulkan app and am looking for a 2D solution for the UI.

Current PRs

VS bug #727962

mattleibow commented 7 years ago

Most certainly we are going to be adding this. At this time no-one has asked, so we never got around to it, but it should be relatively simple to add. It just needs the few setup types, and then that gets handed over the the GRContext to continue as normal.

Feel free to have a go and send a PR :)

jcoder58 commented 7 years ago

Feel free to have a go and send a PR :)

I'll take a look at it. Is there anyway to build just the Desktop?

mattleibow commented 7 years ago

I usually just build externals-windows on Windows and externals-osx on macOS. This is the native bits, and then you can use the unit test projects to test. If you want to run a UI with it, you can use the samples. Just uninstall the SkiaSharp NuGet and add the project references.

The samples use NuGets because they are aimed at people just downloading and running the samples. For dev, I use the WindowsSample or the MacSample. You should just need to add the /binding/Binding/Binding.shproj and the /binding/SkiaSharp.[Desktop/OSX]/*.csproj

If you are using Linux, then there is just the one x64 platform and libs.

Looking forward to seeing what you are doing.

jcoder58 commented 7 years ago

Tried running WindowsSample and am getting:

Unable to load DLL 'libSkiaSharp.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

libSkiaSharp.dll is installed in the x86/x64 folders. I have Microsoft Visual C++ 2015 Redistributable installed (reinstalled it to make sure it was the latest).

Also, the link to the Microsoft Visual C++ 2015 Redistributable in the readme is broken.

mattleibow commented 7 years ago

@jcoder58 libSkiaSharp mush be in the same directory as the SkiaSharp.dll. Are you building as x86 or x64? AnyCPU should be working now, but maybe not. Are you using the WindowsSample, but with the project references? Also, make sure you uninstall the SkiaSharp NuGets - or at least delete the SkiaSharp.dll reference from the NuGet.

mattleibow commented 7 years ago

@jcoder58, If you are still working, we can chat on https://gitter.im/xamarin/XamarinComponents and get you started.

jcoder58 commented 7 years ago

Well, that didn't go far. Skia doesn't have the Vulkan backend in the C API :(.

mattleibow commented 7 years ago

That is what I am doing with SkiaSharp... the C API. And then the C# API on that.

You could have a stab at that, it is not too tough once you get the hang of it. I basically just have a C method that calls the real C++ method. You can just do what is needed, and then clean up later.

Kavignon commented 6 years ago

What's the current state of this and what's missing for C# ?

mattleibow commented 5 years ago

This is something that we will be looking at in the future.

MarchingCube commented 4 years ago

For people still waiting for this: we are starting to merge back our changes via https://github.com/mono/SkiaSharp/pull/897.

BradChase2011 commented 4 years ago

Whats the current status on this? I would love to do some testing and see what type of performance I get on our Vulkan rendering.

MarchingCube commented 4 years ago

@BradChase2011 Unfortunately our PR got stuck in the review process and we can't do much about it since it is us waiting for feedback. For us that means we have to keep a fork running and merge manually. Internally we are using SkiaSharp with Vulkan from several months without issues.

mattleibow commented 4 years ago

That is my fault. Since there weren't that many votes/requests for Vulkan, it sort of slid down the list. I do still want to merge this. @MarchingCube what platforms are you using Vulkan on?

MarchingCube commented 4 years ago

We are running on windows exclusively at the moment. I think our test can be adopted to run on other OSes.

mattleibow commented 4 years ago

@MarchingCube OK. I merged the PRs into "official" branches that I will keep up to date. I made some comments that I think we would want before we merge: #1010 and https://github.com/mono/skia/pull/69. I want to get this in, but my humanity is holding me back 😉 We will accept PRs to the dev/vulkan branch, and I will keep it up to date. So, you should be able use the branches with minimal work.

It is not the best answer of "merged", but until we get more of the API bound, I think we need a little longer.

To get more time allocated to this section of the API, you might need a few more 👍. Share this issue with friends and family and then I can take it up the ladder of priority.

MarchingCube commented 4 years ago

@mattleibow Thanks for the update, we already switched internally to use that branch (it already makes our life easier so thanks for that). About getting more API bound - I guess others might need to chime in with their requests since for us it already covers 100% of what we need at the moment.

I guess biggest factor will be actually testing with other OSes and checking if current API covers it.

Also the issue got a bit more publicity now (no.3 top upvoted issue) 😄

BradChase2011 commented 4 years ago

@mattleibow @MarchingCube Sorry for the late response guys, had other pressing matters. I have to wrap up some code, but hopefully I can test this on windows and droid (and AndroidTV) early/mid next week. Thanks a ton for the work! Cant wait to test!

mattleibow commented 4 years ago

@MarchingCube I see you got the family involved 😜 Rather than actual features, I am concerned that the API has changed a fair bit from now to the current head: https://github.com/google/skia/tree/master/include/gpu/vk

Even the VkInterface is gone, so it might be useful to see what they are doing now, and then make this API work like that - even if we have to do a bit of extra work in managed layer for now. This way, we can avoid a breaking change when people update.

mattleibow commented 4 years ago

Rebased the PRs on the later m80 codebase. We can now work from there.

mattleibow commented 4 years ago

This has been pushed to the preview feed for initial testing:

BradChase2011 commented 4 years ago

@mattleibow I tried to use this, but SharpVk has a bug in their Droid version where it cant get a surface. I posted the fix for me on his issues page https://github.com/FacticiusVir/SharpVk/issues/55. I run a modified version of his wrapper to be able to run on Droid. So what is the best way to be able to build the vulkan version of this using my SharpVk fork?

mattleibow commented 4 years ago

@BradChase2011 at this point, this PR only builds skia with Vulkan support for Win32.

To build an Android skia with Vulkan, you will have to change the property in the native/android/build.cake. And then build the new native library.

I'll have a look at this soon an see what breaks. Or, you can try by opening a PR to change that property. I think it is skia_uses_vulkan or something.

mattleibow commented 4 years ago

Interesting... seems to build for android just fine so far... I thought this was just for Android N+ and I was thinking I had to do something... Hmmm.

I'll create a new PR and then you can try that.

mattleibow commented 4 years ago

Added this PR that will build for Android and Linux: https://github.com/mono/SkiaSharp/pull/1287

Fingers crossed it Just Works ™️

mattleibow commented 4 years ago

@BradChase2011 I just pushed out the Android/Linux PR as a NuGet to the preview feed as 2.80.0-pr.1287.3

mattleibow commented 4 years ago

I hacked a few things and is seems to at least create a GRContext on Android. I tested with a modified version of https://github.com/discosultan/VulkanCore.

mattleibow commented 4 years ago

Closing this now as all the supported platforms (Win32, Linux, Android) are building.

BradChase2011 commented 4 years ago

Awesome, thanks much! Ill give it another shot here as soon as I get a chance to jump back into playing with libraries. As far as I know SharpVk was the only wrapper I could find that has the latest bindings for Vulkan 1.2, it seems all the others stopped being updated on earlier versions.

garrynewman commented 3 years ago

I've been trying to get this to work for a couple of days but I'm failing. Is there an example of rendering to the backbuffer? The c++ examples I've found seem to create a texture to render to rather than going straight at the screen.

Should we be doing SKSurface.CreateAsRenderTarget or SKSurface.Create? Should we be manually filling out a GRVkImageInfo? Which properties need to be filled in? Is GRVkImageInfo.Alloc needed if you're attaching to an existing texture?

Everything I try seems to end up with SKSurface.Create* returning null.

emmauss commented 3 years ago

@garrynewman have you found a way to create a vulkan sksurface

garrynewman commented 3 years ago

No

mattleibow commented 3 years ago

Maybe @MarchingCube can help? I believe that they got that working pretty well all over...

MarchingCube commented 3 years ago

@mattleibow @garrynewman Missed the notification until I started poking around in SkiaSharp again :)

Long story short - Initializing Skia Vulkan surface is not nearly as easy as in OpenGL :)

Setup:

  1. Make sure that you initialize your Vulkan devices and instance
  2. Create your platform KHR vulkan surface (on windows it is Win32SurfaceKHR)
  3. Create swapchain from the surface and obtain images that can be rendered to from it.
  4. Each image needs to be wrapped into GRBackendRenderTarget and you need to pass filled in GRVkImageInfo (we are not setting Alloc to anything).
  5. You can use SKSurface.Create and give it created render target, GRContext and it will create Vulkan accelerated backbuffer based Skia surface.

Rendering:

  1. Obtain the next image index from the swapchain
  2. Transition obtained image into color attachment layout
  3. Draw here
  4. Flush drawing commands from the canvas and context
  5. Transition obtained image into present source layout
  6. Present swapchain image

This description is quite simplified and omits several parts that vary based on your app - if you want to render all the time you need to also submit fences/semaphores before/after rendering to make sure that you don't render too fast and that rendering is actually done.

BradChase2011 commented 3 years ago

@MarchingCube Thanks for the info! If you have extra time, I would love for some more info on how to get this running. We have a full UI library based on Vulkan and Skia for drawing vectors.

So a normal path we take right now is to take say an SVG, and then load it into a SKBitmap and SKCanvas and then DrawPicture and from there take the pixels, convert them into our format and push it over to the GPU Image.

I am having a hard time understanding how that changes into using the Vulkan version of drawing. Do you have a small example of setting up the different GR--- objects? Or do you have any links to some good examples or any examples hah that helped you guys get moving forward?

I guess to be clear, we don't write direct to the back buffer, we write to textures and then use those later on to write to the back buffer.

Anything you can add or link to would be GREATLY appreciated, I cant seem to find any info anywhere.

EDIT: I cant seem to figure out how to link an SKBitmap over to the GRBackendRenderTarget or whatever is needed to push it into an Image on the vulkan side...

EDIT2: Using GrContext.CreateVulkan, always returns null, cant seem to figure out what I am missing there either... Maybe it has to do with not setting GetProcedureAddress, but I am not sure what that property needs or does... NM, I was able to get it to return a context using the code from https://github.com/mono/SkiaSharp/blob/a285919b8f6721f07986fe45ca1417e8524ecce5/tests/VulkanTests/VkContexts/Win32/Win32VkContext.cs