Documentation is incorrect for Vulkan context creation

117 views
Skip to first unread message

Kyle White

unread,
Sep 11, 2021, 5:31:36 PM9/11/21
to skia-discuss
I've been trying to init a Vulkan context.  I referenced the following page:

The documentation tells you to do the following:
sk_sp<GrContext> context = GrContext::MakeVulkan(vkBackendContext);

I was on m91 and GrContext didn't exist (I grepped the entire source) so I tried m95.  Same deal.  For what I can understand, m95 is the latest. There is no struct declaration for it.  All over the code there are comments are referencing GrContext but it's just in comments, there is absolutely no struct declaration of it anywhere.  I figured it was some new thing getting integrated but if its not in the latest m95 then where could it be?

The documentation needs dates.

Kyle White

unread,
Sep 11, 2021, 6:51:39 PM9/11/21
to skia-discuss
sk_sp<GrDirectContext> sk_context = GrDirectContext::MakeVulkan(GrVkBackendContext());

compiles, but it returns a null smart pointer.  I'm linking against vulkan.1 and the lunarg examples work fine for me on the macbook pro 16" from 2019

Pedro Arthur

unread,
Sep 11, 2021, 7:20:29 PM9/11/21
to skia-d...@googlegroups.com
I had the same issue a while ago. The following snippet did work:

        GrVkBackendContext grc{vkinstance, vkpdevice, vkdevice, vkqueue, queue_index, VK_API_VERSION_1_0};

        grc.fGetProc = [](const char *name, VkInstance inst, VkDevice dev) -> PFN_vkVoidFunction {
            if (dev != VK_NULL_HANDLE) {
                return vkGetDeviceProcAddr(dev, name);
            }
            return vkGetInstanceProcAddr(inst, name);
        };


        if (!context) {
            context = GrDirectContext::MakeVulkan(grc);
            gpu_surface = SkSurface::MakeRenderTarget(context.get(), SkBudgeted::kNo, info);
            if (!gpu_surface) {
                printf("skia initialization failed!\n");
                exit(1);
            }
        }


--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/85f3f74e-e6ec-4d3e-a7c5-6a6b5577d816n%40googlegroups.com.

Kyle White

unread,
Sep 12, 2021, 11:51:29 AM9/12/21
to skia-discuss
Thanks.  It seems like I'll have to be the one managing the vk instance / device / queue / etc handles, correct?  I would think Skia would have that handled internally for the case above that is 'supposed' to work, right?  Looks like I have no choice on the matter though..

Kyle White

unread,
Sep 12, 2021, 11:56:20 AM9/12/21
to skia-discuss
I suppose it really needs that, otherwise theres no real way to embed skia operation-wise in the pipeline. Looks like I'll have to go through the vulkan tutorials again, it's been like 2 years.

Pedro Arthur

unread,
Sep 12, 2021, 12:08:30 PM9/12/21
to skia-d...@googlegroups.com
Em dom., 12 de set. de 2021 às 12:56, Kyle White <ky...@krworks.com> escreveu:
>
> I suppose it really needs that, otherwise theres no real way to embed skia operation-wise in the pipeline. Looks like I'll have to go through the vulkan tutorials again, it's been like 2 years.

I think so.

If you want I can provide a vulkan setup snippet I use.

Kyle White

unread,
Sep 12, 2021, 1:57:33 PM9/12/21
to skia-discuss

Luboš Luňák

unread,
Sep 13, 2021, 2:28:53 AM9/13/21
to skia-d...@googlegroups.com
On Sunday 12 of September 2021, Kyle White wrote:
> At the moment I'm doing everything but coding based on the following:
> https://github.com/Noxagonal/Vulkan-API-Tutorials/blob/master/Tutorial%20-%
>200005%20-%20GLFW%20Example/main.cpp

You can have a look at Skia's tools/sk_app for how to use Skia with Vulkan.

--
Luboš Luňák
l.l...@collabora.com

Kyle White

unread,
Sep 13, 2021, 2:01:09 PM9/13/21
to skia-discuss
Thanks I'm doing that now.  After getting a valid instance, device, queue, etc the init above with the params given still returns NULL.

Kyle White

unread,
Sep 13, 2021, 2:09:32 PM9/13/21
to skia-discuss
I'm using MoltenVK and the associated Vulkan wrapper on Mac.  I traced the Vulkan initialization in sk_app to the following:
#ifdef SK_VULKAN
inline std::unique_ptr<WindowContext> MakeVulkanForMac(const MacWindowInfo&, const DisplayParams&) {
// No Vulkan support on Mac.
return nullptr;
}
#endif


Now does this mean that indeed with or without wrapper there is no support?  MoltenVK uses Metal underneath.  Definitely stuck now.

Regards

Jim Van Verth

unread,
Sep 13, 2021, 2:11:11 PM9/13/21
to skia-d...@googlegroups.com
Since Skia has Metal support, we recommend using that directly rather than MoltenVK.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.


--

Jim Van Verth | Software Engineer | jvan...@google.com | 919-210-7664

Kyle White

unread,
Sep 13, 2021, 2:22:38 PM9/13/21
to skia-discuss
Totally get that, but that means I would be using two apis in my code now.  That's pretty unheard of for a gfx stack.

Greg Daniel

unread,
Sep 13, 2021, 2:42:16 PM9/13/21
to skia-discuss
When you say you'll be using two apis, are you saying you are already using Vulkan for other things outside of Skia? If so shouldn't you already have the whole Vulkan context setup?

Also The WindowContext stuff you linked to earlier is just used for Skia tools and testing which is why we don't make Vulkan on Mac. But nothing stops you from setting up your own Vulkan context via MoltenVk and still using Skia. However, as Jim said, on mac you really should directly be using Metal for Skia (and I imagine most other applications).

Brian Salomon

unread,
Sep 13, 2021, 4:20:52 PM9/13/21
to skia-d...@googlegroups.com
All the code in tools/ is really just there to enable our test tools and demo apps. It's not meant to be used in your code other than as an example. I'd refer to VulkanWindowContext.cpp and adapt it for your MoltenVK setup.

If you're going through GrDirectContext::MakeVulkan() with all the Vulkan objects (instance, device, queue, ...) configured and it's not working you may just need to step through and tell us where it's failing. As you found out we aren't testing the Vulkan backend on MoltenVK so I guess it's not too surprising there's an issue. We'd probably accept patches that would get it working.

Kyle White

unread,
Sep 14, 2021, 1:25:57 PM9/14/21
to skia-discuss
I've got a couple things to report so far.  Without an 'allocator' defined theres a simple null pointer crash at GrVkAMDMemoryAllocator.cpp, search for text:
extensions->hasExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, 1)

I went ahead and encapsulated that with a check on extensions
info.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
(extensions && extensions->hasExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, 1) &&
 extensions->hasExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, 1)))
    info.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;

Then of course it took me a little while to get past an incorrect texture format specifier for the VkImage and Skias validation of such supported formats.  Took me a while to know its VK_FORMAT_R8G8B8A8_UNORM that i need to pass (I had tried UINT and SINT), and those correlate ok with kRGBA_8888_SkColorType which maps to the GrColorType::kRGBA_8888.

After the formats and such went through I discovered I didn't have a SkAllocation scheme on the SkImage which got rid of some more validation errors..  Now the one I cannot get past is this:

VUID-VkImageSubresourceRange-levelCount-01720(ERROR / SPEC): msgNum: 357932245 - Validation Error: [ VUID-VkImageSubresourceRange-levelCount-01720 ] Object 0: handle = 0xf443490000000006, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x15559cd5 | vkCmdPipelineBarrier: subresourceRange.levelCount is 0. The Vulkan spec states: If levelCount is not VK_REMAINING_MIP_LEVELS, it must be greater than 0 (https://vulkan.lunarg.com/doc/view/1.2.189.0/mac/1.2-extensions/vkspec.html#VUID-VkImageSubresourceRange-levelCount-01720)

    Objects: 1

        [0] 0xf443490000000006, type: 10, name: NULL

My SkImage has a mipLevels = 1.  This 'levelCount' member I'm not sure what struct this is associated to, but it seems incorrect about my image.

This image is passed into GrVkImageInfo along with the same format specifier.  Sorry for the verbosity but I tried to piece together the sequence here so you know all the info going into the skia stack.

GrDirectContext *ctx = Skia::Context()->sk_context.get();
auto imi = GrVkImageInfo { };
imi.fFormat = VK_FORMAT_R8G8B8A8_UNORM; 


VkImage image = VK_NULL_HANDLE; 

VkImageCreateInfo im = {};
VkDeviceMemory imem;
VkMemoryRequirements mreq;
VkMemoryAllocateInfo ai {};

// setup image creation info
im.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
im.imageType = VK_IMAGE_TYPE_2D;
im.extent.width = sz.x;
im.extent.height = sz.y;
im.extent.depth = 1; // ? 4 should be right since this is an allocation parameter
im.mipLevels = 1;
im.arrayLayers = 1;
im.format = VK_FORMAT_R8G8B8A8_UNORM;
im.tiling = VK_IMAGE_TILING_OPTIMAL;
im.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // was VK_IMAGE_LAYOUT_PREINITIALIZED;
im.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; // was 0
im.samples = VK_SAMPLE_COUNT_1_BIT;
im.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

// create image for device with the above params
vkCreateImage(device, &im, nullptr, &image);
assert(image != VK_NULL_HANDLE);

// fetch image memory requirements
vkGetImageMemoryRequirements(device, image, &mreq);

// setup memory alloc info
ai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
ai.allocationSize = mreq.size;
ai.memoryTypeIndex = find_memory_type(mreq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

if (vkAllocateMemory(device, &ai, nullptr, &imem) != VK_SUCCESS)
     throw std::runtime_error("failed to allocate image memory!");

vkBindImageMemory(device, image, imem, 0);

imi.fImage = image;

auto rt = GrBackendRenderTarget { sz.x, sz.y, imi };
sk_surf = SkSurface::MakeFromBackendRenderTarget(ctx, rt, kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, null, null);


sk_surf is a valid handle, the validation errors occur when its used with canvas ops which I can also post, but I don't want to flood this thing.

Regards

Greg Daniel

unread,
Sep 14, 2021, 1:49:06 PM9/14/21
to skia-discuss
For one you need to fill out the whole GrVkImageInfo struct. It looks like only 2 of its fields are ever filled out.

Second you should pass in a valid GrBackendContext::fVkExtensions struct. There does look to be a bug if you use the deprecated fExtensions flags that the extensions are not correctly passed into the AMD allocator correctly. I can fix that, but you should use the GrVkExtensions struct instead.

Kyle White

unread,
Sep 14, 2021, 2:57:40 PM9/14/21
to skia-discuss
Alright thats where that fLevelCount is, I set it to 1 and basically mirrored the VkImage stuff over.  No validation errors present but also no image present.

It got me looking at the "VK_KHR_swapchain" (VK_KHR_SWAPCHAIN_EXTENSION_NAME) extension which I had commented out prior.  When I add this extension to the device it crashes on vkCreateDevice which is probably an impossible roadblock now.  Without swapchain ability it just isnt a framebuffer I suppose.  This is required correct? 

Greg Daniel

unread,
Sep 14, 2021, 3:04:19 PM9/14/21
to skia-discuss
The Skia only really needs to know if the swapchain extension is present if you plan on giving the VkImage to skia with a layout of VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or plan to ask Skia to change it to that layout. Outside of that, all the swapchain stuff is handled outside of skia. Also since you are using vkCreateImage, that image is not coming from a swapchain. You would need to have created a VkSwapchain and then gotten a VkImage from that to have to worry about the extension and the above layout.

Reply all
Reply to author
Forward
0 new messages