https://github.com/garettbass/gpuc
A header-only C-like shading language compiler that writes Metal, HLSL, GLSL
https://github.com/garettbass/gpuc
Last synced: about 2 months ago
JSON representation
A header-only C-like shading language compiler that writes Metal, HLSL, GLSL
- Host: GitHub
- URL: https://github.com/garettbass/gpuc
- Owner: garettbass
- Created: 2019-08-13T15:59:15.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-08-13T16:01:54.000Z (almost 6 years ago)
- Last Synced: 2025-05-07T00:13:00.487Z (about 2 months ago)
- Language: C
- Size: 39.1 KB
- Stars: 60
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- AwesomeCppGameDev - gpuc - only C-like shading language compiler that writes Metal, HLSL, GLSL (Graphics)
README
# GPUC
A generic shading language compiler that writes metal, HLSL, and GLSL
***GPUC is a work in progress, not ready for prime time.***
The primary motivation was to create a header-only shader language translator that has negligible effect on compile times. Including this should not add more than a fraction of a second to your compile time, unlike other shader translators I tried.
Only the metal backend is actually useful right now, and probably only for simple shaders. The HLSL and GLSL backends have rotted a bit due to some recent changes in the source language.
I initially wrote this over a two week holiday vacation in December of 2017. I was amazed how easy it was to continue building upon when I returned to it many months later. For me, this was the first reasonably useful thing I implemented in C, and since then I have switched to C for the majority of my hobby projects.
## Usage
### Header-only library
```c
// include API declarations as needed
#include "gpuc/gpuc.h"
``````c
// include implementation in one translation unit
#include "gpuc/gpuc.inl"
```### Stand-alone compiler
```sh
» sh gpuc.c --help
usage:gpuc [options]
options:
--help display this usage summary
--ast print AST to stdout
--debug print debug summary to stdout
--test run tests
--glsl translate GPUC to GLSL
--hlsl translate GPUC to HLSL
--metal translate GPUC to Metal
--frag write output to , or '-' for stdout
--vert write output to , or '-' for stdout
``````sh
» sh gpuc.c sample.gpuc --vert - --frag - --metal
```
```c
#include
#includeusing namespace metal;
float4 sample(const texture2d t, float2 uv) {
constexpr sampler s(filter::nearest);
return t.sample(s, uv);
}float4 sample(const texture2d t, float2 uv, const sampler s) {
return t.sample(s, uv);
}struct gpuc {
// float4 sample(texture2d, float2);
// float4 sample(texture2d, float2, sampler);
struct Camera {
float4x4 mvp;
float4x4 mvn;
};struct Vertex {
float3 position [[attribute(0)]];
float4 color [[attribute(1)]];
float4 texcoords [[attribute(2)]];
};struct Fragment {
float4 position [[position]];
float4 color;
float4 texcoords;
};struct Sample {
float4 color;
};constant const Camera& cam;
const texture2d color;
const sampler samp;
Fragment vert(const Vertex v) const {
Fragment f;
f.position = cam.mvp * float4(v.position, 1);
f.color = v.color;
f.texcoords = v.texcoords;
return f;
}};
vertex gpuc::Fragment vert(
constant const gpuc::Camera& cam [[buffer(0)]],
texture2d color [[texture(0)]],
sampler samp [[sampler(0)]],
const gpuc::Vertex v [[stage_in]]
) {
return gpuc{cam, color, samp}.vert(v);
}
#include
#includeusing namespace metal;
float4 sample(const texture2d t, float2 uv) {
constexpr sampler s(filter::nearest);
return t.sample(s, uv);
}float4 sample(const texture2d t, float2 uv, const sampler s) {
return t.sample(s, uv);
}struct gpuc {
// float4 sample(texture2d, float2);
// float4 sample(texture2d, float2, sampler);
struct Camera {
float4x4 mvp;
float4x4 mvn;
};struct Vertex {
float3 position;
float4 color;
float4 texcoords;
};struct Fragment {
float4 position [[position]];
float4 color;
float4 texcoords;
};struct Sample {
float4 color;
};constant const Camera& cam;
const texture2d color;
const sampler samp;
Sample frag(const Fragment f) const {
Sample s;
s.color = sample(color, f.texcoords.st, samp);
return s;
}};
fragment gpuc::Sample frag(
constant const gpuc::Camera& cam [[buffer(0)]],
texture2d color [[texture(0)]],
sampler samp [[sampler(0)]],
const gpuc::Fragment f [[stage_in]]
) {
return gpuc{cam, color, samp}.frag(f);
}
```