About a month ago, I replied to a thread on the Nouveau Mailing List announcing that I would be working on different tasks in order to bring OpenCL/Cuda support to Nouveau. A few days later, I ran away… to Japan for some (quite needed) vacations. Before leaving, I had started working on a first task though: parsing SPIR-V binaries. It was able to parse the SPIR-V header instructions, constants and the different types declarations, nothing major and the code was horrible (well, it still is).
The different tasks to tackle in order to get OpenCL/Cuda support are the followings:
- Compile the OpenCL/Cuda code, or parse a representation of that code; this task will benefit to other drivers as well, as there is nothing Nouveau specific there. We decided to parse the SPIR-V output of OpenCL/Cuda code compilation, as OpenCL 2.0 and OpenCL 2.1 can be compiled to it, and it will also be used as the shader input stream by Vulkan. Regarding Cuda, it is possible to compile Cuda to LLVM IR, and Khronos is working on converting LLVM IR to/from SPIR-V.
- Convert SPIR-V to NV50 IR; this task is now specific to Nouveau.
- Reverse Engineer how the binary driver from Nvidia initialises the card prior to running kernels; this task is also (obviously) specific to Nouveau. Tesla cards have partial compute support, for Fermi and Kepler cards it should be almost done, whereas for Maxwell we still need the signed firmwares from Nvidia. As I mainly own Tesla cards (I only have one Fermi, and one Maxwell beside Tesla cards), I'll start working on Tesla first.
Now, what is the current plan? Well, since I came back from Japan a week ago, I did some code cleanup plus I added parsing functions, branches and variables instructions. I aim to parse memory instructions as well as basic operations such as ADD, MADD, etc. ASAP, before adding some basic transformation from SPIR-V to NV50 IR in order to be able to test compiling really basic fragment shaders from SPIR-V to NV50 IR. Why fragment shaders? Because Nouveau can already handle them, so I can test that compiling a basic shader from GLSL to NV50 IR via SPIR-V still produces the same results as compiling that same basic shader from GLSL to NV50 IR via TGSI (the current path in Nouveau). This way, I have some guarranty that my NV50 IR code generation isn't complete garbage! :D Once this is done (I'd like to have that by the end of next week O:-)), I'll try parallelising between RE'ing compute support on Tesla and expanding the set of instructions parsed from SPIR-V and transformed into NV50 IR.
The code can be found in rMESA, on branch spir-v_to_nv50-ir, though there is absolutely nothing exciting to test/look at right now. The code for compute support will be found in rNOUVEAU on some separate branch that still needs to be created.