Another Year Passes

I meant to blog more, but it seems we’re out of time. As we all know, SGC must go into hibernation at the end of the year to recharge. Workplace safety laws require sufficient rest time be given to meme-rich environments, and you can’t spell SGC without safety.

No, you can’t.

I’ve got two more blog posts that I’m hoping to release before the blog’s hard-earned time off begins.

The first is about OpenCL.

That’s this one.

Zink: Also a CL Driver

We all knew this would happen.

We follow Karol on twitter.

We’ve seen the wild, unhinged tweets from his local pub claiming to have LuxMark or some other insane, CL-based application running on top of who knows what driver.

It was only a matter of time before he cornered me at XDC for a quick “talk”. It was completely normal the way he had no fewer than four laptops physically harnessed to his person as he strutted around in search of hapless driver maintainers upon whom he could foist his latest and least sane project. I wasn’t at all afraid for my life when he told me that, by the time he let me leave the conference hall that day, rusticl would be working on zink.

I’m here blogging about it now, so obviously everything is fine and I’m not still trapped in his basement, but let’s take a look at some of the challenges I faced over that grueling, interminable period of CL bring-up besides lack of water and food.

Shader Types

The first major issue is, of course, that CL shaders are called “kernels”, and they are in the KERNEL stage. Since zink only handles the GL shader stages, this posed a bit of a problem.

Thankfully, kernels are very similar to GL/VK compute shaders, and so it was easy to combine most of the code into the compute blocks.

But this led to the real problem.

Sampler Descriptors

The real problem is that now this is yet another blog post about Vulkan descriptor models.

I know.

Believe me, I know.

I didn’t want to be here either.

In GL, there is the idea of a combined sampler. This descriptor type has both an image and a sampler in a 1:1 ratio.

CL, being the absolute unit of an API that it is, has discrete images and samplers.

Also, unlike with sane APIs, CL allows entirely untyped shader image access, meaning the images have no format or even component type.

If you’re thinking this is more convenient for users, you’re wrong.

Being completely separate, sampled images and samplers cannot just reuse the same codepaths. Instead, it was necessary to add in some hooks that could help translate these descriptors into the existing combined sampler codepaths. Primarily this amounted to:

  • adding shader handling for generating the final sampled image type based on the loads of the sampler and image variables
  • tweaking the descriptor template code to handle samplers and sampled images

Yeah, it wasn’t actually that hard. Because Vulkan descriptors aren’t that hard.

Stop writing about them.

Shader Samplers

The hard part was the shader interface, because Vulkan doesn’t allow untyped image access. So to handle this, I wrote some compiler passes to go through the shaders and add type info to the variables based on their usage.

I know what you’re thinking.

You’re thinking why didn’t this total lunatic writing a CL frontend in Rust just add type info to the variables before you got them? Wouldn’t that have saved you a lot of work?

It’s a great question. One of the best. And your follow-up? Incredible. Honestly, I knew that all of my readers were smart, but I didn’t realize you were this brilliant.

I don’t have an answer to this, and when asked, Karol just told me I’d earned myself another week in the pit. Whatever that means.

It’s Over.

Zink (on RustiCL) is done.

There’s nothing left (for me) to do, and anyone who says otherwise is wrong.

If you try it out and it doesn’t work, complain to Karol. On his twitter. Or in the Phoronix comments, where he has at least three different accounts.

Written on October 26, 2022