[Mesa-dev] [RFC PATCH 00/17] Introducing SPIR-V support to clover

Pierre Moreau pierre.morrow at free.fr
Wed May 3 21:56:48 UTC 2017

Hello everyone,

I have been working on converting SPIR-V to NVIR in order to run OpenCL kernels
on Nouveau, and I would like to submit the first part of that work for review.
Pieces from the SPIR-V to NVIR conversion work will be submitted once I have
cleaned it up and this series has progressed through the reviewing process.

What’s in this Series?

The focus of this series is to let clover accept SPIR-V binaries, either
through `clCreateProgramWithBinary()`, or through `clCreateProgramWithIL()`.
The latter function is the proper way to feed SPIR-V binaries using the OpenCL
API, however it was only introduced in OpenCL 2.1 (more on “why supporting
SPIR-V through `clCreateProgramWithBinary()` can be interesting” further down).

As several SPIR-V binaries can be linked together using the OpenCL API, I
implemented a SPIR-V linker, which is not perfect, but does the job. I tested
linking against a variable, a function, a library, and a function containing a
switch statement; switch-statements require you to keep some extra stuff around
to be properly parsed.
I also added a few “utilities” functions for retrieving and setting a word /
retrieving a string from a SPIR-V binary, and converting a SPIR-V binary to the
same endianness as the host CPU.

For validating SPIR-V binaries, I use an external tool, SPIRV-Tools [1]. It
could also be used in anv, and possibly radv if there is no validation done
already, but I haven’t looked into that.

A few modifications have been made to the pipe interface, to add a define for
the SPIR-V IR, and store the program’s byte-size along the program in
`struct pipe_compute_state`. The latter will only be needed by the consumer of
the SPIR-V, which is not part of this series. However, since clover needs to
fill that information in and I was modifying clover already, I decided to add
the new attribute in this series.


* As there is no upstream version of LLVM which can produce SPIR-V out of
  OpenCL code, clCreateProgramWithSource will refuse to work if the target IR
  is SPIR-V, for now.

* Optimisation linking options are parsed by the SPIR-V code in clover but
  are not passed along to the linker as it does not support them.

To Improve

The SPIR-V binary resulting from the linking of multiple SPIR-V binaries could
be cleaned up:

* As capabilities are simply copied from all the involved binaries, you can end
  up with multiple times the same capabilities in the resulting binary; this
  shouldn’t have any impact though.

* Similarly, types can end up being duplicated under different IDs, which
  should have no other impact than making SPIR-V validators unhappy.


Being able to feed SPIR-V binaries through `clCreateProgramWithBinary()` is not
really useful at the moment: the same can be achieved using
`clCreateProgramWithIL()`. However it will be interesting once there is an
upstream version of LLVM which can generate SPIR-V binaries, as the application
could query the binary created by `clCreateProgramWithSource()` on the first
run, and give it to `clCreateProgramWithBinary()`on later runs.

Once NIR supports pointers, and anything else that could be missing to support
OpenCL kernels, it should be possible and easy to convert input SPIR-V
binaries to NIR, for drivers that do not accept SPIR-V as IR.

I have sent patches to Mesa in the past, but never series, so the splitting of
the patches in the series could be completely wrong, and I apologise for that
in advance.
Also, I am sure I abused of macros, gotos and manual memory managements, as I
am not that comfortable at writing too much C code: I’ll try to learn from
your comments.

Thank you in advance for reviewing/commenting,

[1]: https://github.com/KhronosGroup/SPIRV-Tools/

Pierre Moreau (17):
  auxiliary: Introduce utilities for SPIR-V binaries
  auxiliary: Implement a linker for SPIR-V binaries
  include/pipe: Define SPIRV as an IR
  include/pipe: Store the byte-size of a SPIR-V binary
  include/CL: Add clCreateProgramWithIL from OpenCL 2.1
  include/CL: Add new option to clGetProgramInfo from OpenCL 2.1
  configure.ac: Check for SPIRV-Tools header and library
  clover: Fill in the program byte-size in pipe_compute_state
  clover: Add additional functions to query supported IRs
  clover/spirv: Import spirv.hpp11 version 1.0 (rev 10)
  clover/spirv: Add functions for parsing arguments, linking programs,
  clover: Refuse to compile source code to SPIR-V
  clover: Handle the case when linking SPIR-V binaries together
  clover: Accept SPIR-V binaries in clCreateProgramWithBinary
  clover: Implement clCreateProgramWithIL from OpenCL 2.1
  clover: Add a pointer property to return ILs
  clover: Handle CL_PROGRAM_IL in clGetProgramInfo

 configure.ac                                       |   16 +
 include/CL/cl.h                                    |    7 +
 include/CL/cl_platform.h                           |    1 +
 src/gallium/auxiliary/Makefile.am                  |    1 +
 src/gallium/auxiliary/Makefile.sources             |    6 +
 src/gallium/auxiliary/spirv/spirv_linker.c         | 1324 ++++++++++++++++++++
 src/gallium/auxiliary/spirv/spirv_linker.h         |   67 +
 src/gallium/auxiliary/spirv/spirv_utils.c          |   75 ++
 src/gallium/auxiliary/spirv/spirv_utils.h          |   86 ++
 src/gallium/include/pipe/p_defines.h               |    1 +
 src/gallium/include/pipe/p_state.h                 |    1 +
 src/gallium/state_trackers/clover/Makefile.am      |   10 +-
 src/gallium/state_trackers/clover/Makefile.sources |    4 +
 src/gallium/state_trackers/clover/api/program.cpp  |   74 +-
 src/gallium/state_trackers/clover/core/device.cpp  |   11 +
 src/gallium/state_trackers/clover/core/device.hpp  |    3 +
 src/gallium/state_trackers/clover/core/kernel.cpp  |    1 +
 src/gallium/state_trackers/clover/core/program.cpp |   80 +-
 src/gallium/state_trackers/clover/core/program.hpp |   14 +
 .../state_trackers/clover/core/property.hpp        |   39 +
 .../state_trackers/clover/spirv/invocation.cpp     |  481 +++++++
 .../state_trackers/clover/spirv/invocation.hpp     |   40 +
 .../state_trackers/clover/spirv/spirv.hpp11        |  952 ++++++++++++++
 23 files changed, 3272 insertions(+), 22 deletions(-)
 create mode 100644 src/gallium/auxiliary/spirv/spirv_linker.c
 create mode 100644 src/gallium/auxiliary/spirv/spirv_linker.h
 create mode 100644 src/gallium/auxiliary/spirv/spirv_utils.c
 create mode 100644 src/gallium/auxiliary/spirv/spirv_utils.h
 create mode 100644 src/gallium/state_trackers/clover/spirv/invocation.cpp
 create mode 100644 src/gallium/state_trackers/clover/spirv/invocation.hpp
 create mode 100644 src/gallium/state_trackers/clover/spirv/spirv.hpp11


More information about the mesa-dev mailing list