shithub: gpufswip

ref: 61f6908ca1a0c7b279e840a992e8d4307afd78ad
dir: /gpufs.txt/

View raw version
[[[ms
.FP lucidasans
. \" no header
.ds CH "
.
.HTML "GPU Filesystem for Plan 9"
.TL
GPU Filesystem for Plan 9
.AU
Joel Fridolin Meyer
joel@sirjofri.de
.AI
.AB
Many modern computer systems have dedicated hardware for computing graphics and other floating point-heavy operations.
GPU manufacturers and organisations try to standardize interfaces, often providing standard APIs and drivers for their specific hardware.
This WIP paper tries to describe a potential filesystem for Plan 9 for dedicated GPU hardware.
.AE
]]]

# Graphics or not graphics?

GPU hardware evolved from very specified pipelines for 2D rendering to 3D rendering and more generic interfaces.
In the last few years GPU manufacturers started to sell ``unified shaders'' that allow even more generic computing pipelines.
The trend towards hardware accelerated AI computation and the recent trend to more specialized graphics processing¹ justifies to drop native graphics processing support, at least in an initial implementation.

[[[ms
.FS
¹ Epic Games' Nanite does rasterization within a shader.
They also plan to make Nanite compute the shading on the software level. [Nanite]
.FE
]]]

This allows us to ignore many graphics-specific parts of the API, as well as potential drivers.
Of course it also makes our interface a non-standard interface, but due to the nature of Plan 9 filesystems this should be fine.

# The implementation

Since driver development is hard and it's hard to get reference implementations for common GPU drivers, this first implementation will be fully CPU based.
The interfaces however should look as similar as possible to a true GPU implementation.

Due to the nature of filesystems, this should make it easy to ``upgrade'' applications to actual GPU hardware: Using a different GPU filesystem is all that's needed.
The software itself doesn't need to change.

Furthermore, since real drivers are a rarity, this makes software that relies on the GPU filesystem work on systems that don't have dedicated graphics.
Obviously, there'll be a huge speed difference in this case.

# The filesystem interface

This implementation will provide a very simple interface that's based on existing APIs, mostly OpenGL and Vulkan.

Due to this simplicity and the fact that I still have a lot to learn about GPUs, the interface is not set in stone, and many details are missing.
In fact, the proposed interface might not work at all with real hardware, but it can be a start.

The shader language is SPIR-V, which is used in Vulkan as an intermediate language.
The shaders are loaded into the filesystem, which will compile them further down to the specific hardware, so they can be executed. [SPIR-V]

Buffers are represented as files within the filesystem.
This gives us the flexibility to access the buffer contents by standard file IO.

Management and control is handled via a console like interface as a control file.
Using this interface, it is possible to initialize new shaders and allocate new buffers, as well as control binding and program execution.

Shaders and buffers are represented as the general concept of ``objects''.
Each object has it's own subdirectory within the GPU filesystem (1).
Initializing a new shader or buffer using the control file, we can read back the ID of the object.
With that, our application can know which object directory to access.

[[[ms
.DS B
.CW /dev/gpu "." "1. The GPU filesystem "
.B1
.CW
/ctl        (control file)
/0/buffer   (sample buffer file)
/1/shader   (sample shader file)
.B2
.DE
]]]

Shaders and buffers can be loaded by writing to their files, readback is as simple as it sounds (2).

[[[ms
.DS B
2. Loading shaders and buffers.
.B1
.CW
cat myfile.spv > /dev/gpu/1/shader
cat mydata.bin > /dev/gpu/0/buffer
…
# compile shader and run, see (3)
…
cp /dev/gpu/0/buffer > result.bin
.B2
.DE
]]]

The filesystem can't know when a shader is loaded completely.
Because of that, it is necessary to manually tell it to compile the shader.
This can be done by issuing the ‥compile‥ command on the shader control file (3).

Since a single SPIR-V program can contain multiple entry points (‥OpEntryPoint‥), it is necessary to specify which shader function to run (3).

[[[ms
.DS B
3. Compiling and running a shader.
.B1
.CW
echo c > /dev/gpu/1/ctl
echo r main > /dev/gpu/1/ctl
.B2
.DE
]]]

Binding buffers and shaders is something I still have to think about.


# State of code and future work

The code currently covers the described filesystem interface completely, however not all functionality is implemented.
Furthermore, there are bugs to be expected. [gpufs]

Language-wise, there's a SPIR-V assembler as well as a SPIR-V disassembler.
Both are far from feature complete according to the SPIR-V specification, missing instructions can be added easily.

It is planned to build the embedded SPIR-V compiler as soon as possible, as well as the runtime engine, so we can finally run shaders and use the filesystem as intended.

Due to the lack of actual GPU hardware support and the fact that the first implementation is single threaded I don't expect much performance gain compared to other implementations of the same logic.
However, the interface is generic enough to allow applications to use different GPU implementations: GPU hardware, CPU hardware (single or multi threaded), network scenarios.

It also makes sense to think about future integrations into devdraw: the GPU filesystem could control actual images of devdraw and enable faster draw times for graphics rendering.

Since SPIR-V is very low-level, it also makes sense to develop shader compilers for higher level languages like GLSL or HLSL.
Applications are developed by different people and for different reasons, so those compilers should not be part of the specific filesystem implementations.


# References

[[[ms
.nr PS -1
.nr VS -2
.IP "[Nanite]" 10
Epic Games, ``Unreal Engine Public Roadmap: Nanite - Optimized Shading'',
.CW https://portal.productboard.com/epicgames/1-unreal-engine-
.CW public-roadmap/c/1250-nanite-optimized-shading ,
2024.
.IP "[SPIR-V]" 10
The Khronos Group Inc., ``SPIR-V Specification'',
.CW https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html ,
2024.
.IP "[gpufs]" 10
Meyer, ``gpufs'' and ``spirva'',
.CW https://shithub.us/sirjofri/gpufs/HEAD/info.html
and
.CW https://shithub.us/sirjofri/spirva/HEAD/info.html ,
2024.
]]]