If you are developing a GPU override deformer in Maya 2016, you are provided with a fairly straight forward process to build the OpenCL kernel. However, this involves you providing the source code of the kernel in a separate file in plain text. This isn’t too big of a deal if you are giving away your plugin and protecting the code isn’t needed. But maybe you want to either protect your work due to licensing or some proprietary technology that you don’t want to share with the world. Whatever the reason is, I will walk you through a method to include your OpenCL kernel from inside your compiled plugin code without having the external source code passed along to your users.

The basic process is to convert your kernel file (myKernel.cl) into a header file (myKernel.h) and including it into your plugin source code. Now instead of loading the kernel through the file, we use a char data type containing the same code. The result will be the same, but you are embedding the kernel code inside your compiled plugin instead of a separate file that someone can open. In the future we can take advantage of new tools such as Spir-V. There are different methods for doing this conversion, but for this tutorial I am going to use CMake for reasons I will explain in more details later.

Before you go any further, you should first make sure your kernel loads and works correctly using Maya’s examples just to rule out where the source of a problem could be. If you want to take this tutorial to the next level, you can use both methods of including your kernel code. For example you can use external kernel file for development and when you are ready to ship the plugin, you can build it with this method.

What you will need:

  • Your MPxGPUDeformer code that is prepped according to Maya’s requirements and successfully loads and runs your OpenCL kernel.
  • Your OpenCL kernel as “cl” file.
  • CMake(optional) – I provide script that performs the conversion process every time you build for painless source code changes.

Conversion to header file

The goal is to take the code in your OpenCL kernel file (.cl) and create a new file that can be included in your plugin source code. For this we will use a header file and use a normal #include to include it.

Lets take a look at the identityNode example that comes with Maya’s devkit. Here is the kernel code:

Now we want to dump this file into a char pointer in the the header file which starts like this:

Now will append each line of the kernel and surround it with quotes, include a newline character before the ending quote and add a backslash at the end of the line so it will continue to the next line. Here is the desired result:

From this resulting header file, we would now just include it in the GPU deformer source code:

Automating the conversion

Now this would be a pain to do this by hand which is why we will now use your favorite scripting language to automate this process. You can use whatever language or method you like, such as Python, bash, powershell, etc. For me, I will implement this task using CMake since most of my project now use this and is a great tool for cross platform developing. It has built-in scripting support so I don’t have to depend on any particular OS or tool to be installed. Also it already has support to execute commands at different stages which makes it really powerful and useful. It’s not the easiest tool to use, but for simple things it’s very handy.

There are two steps to do this in CMake, the first is to add a custom command in your CMake project files. This tells CMake to run this command when the given target is about to be built.

In the above code, it will call a CMake script called “convertClKernel.cmake” in the source directory. It will pass it three additional arguments: the path to the source directory that contains the kernel file, the name of the kernel cl file, and the header file I want to write the output to.

The second part is the CMake script that performs the conversion and outputs a header file. Below is the code that does the work (convertClKernel.cmake)

This is not 100% bullet proof but it does the job in most cases. So that should generate the header file for you just in time to include it in the compiling. Next I will show to to use the included header to build the kernel.

Building the kernel

Update: It seems that in Maya 2016 extension 2, they added a new function to the MOpenCLInfo class that will build the kernel with a string, so this is a more convenient function than the below. But I’ll leave it for reference. Here is a more updated example:

 This is what you would have to do in before extension 2 (for reference):

In this step, we will take the included kernel header which is simply a char pointer and use that to build the kernel. Maya provides a convenience method to do this with a single call with kernel file, but doesn’t provide a similar one with a string, so we will have to use OpenCL calls ourselves but the result will be the same.

So we will first replace the existing you probably are using:

With this code:

So this will take the char pointer “KernelSource” from our header file from before and build the kernel for it. The last line is the MAutoCLKernel variable that will manage the kernel reference for you.

So that is all it takes! You should now be able to compile your plugin and use the GPU override deformer like originally with no difference. If you did get an error, check the header file for possible illegal characters or missing quotes. Now you can share your plugin without packaging up your kernel code along with it!

Comments? Suggestions? Problems? Contact me and tell me!