[Mesa-dev] [RFC PATCH 00/17] Introducing SPIR-V support to clover
pierre.morrow at free.fr
Wed May 3 21:56:48 UTC 2017
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 . 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.
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
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
Thank you in advance for reviewing/commenting,
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