Using <shady.h> #
The <shady.h>
header includes definitions for intrinsics and macros that are unique to shaders and not exposed in the C/C++ standard librairies.
It is not necessary to include this file in every translation unit, only in the files where you want to use those features, and it is also required to annotate shader module entry points.
Vector types #
Vcc makes uses of the existing OpenCL C support in Clang and exposes small vec
-types as also found in GLSL. These are typedef’d as such:
typedef float vec4 __attribute__((ext_vector_type(4)));
typedef float vec3 __attribute__((ext_vector_type(3)));
typedef float vec2 __attribute__((ext_vector_type(2)));
typedef int ivec4 __attribute__((ext_vector_type(4)));
typedef int ivec3 __attribute__((ext_vector_type(3)));
typedef int ivec2 __attribute__((ext_vector_type(2)));
typedef unsigned uvec4 __attribute__((ext_vector_type(4)));
typedef unsigned uvec3 __attribute__((ext_vector_type(3)));
typedef unsigned uvec2 __attribute__((ext_vector_type(2)));
Component swizzling on those types is supported.
Entry points #
Shader entry points need to be annotated with one of:
fragment_shader
vertex_shader
compute_shader
- Also requires setting
local_size(x, y, z)
- Also requires setting
Resources / Pipeline layout stuff #
Vulkan shaders have to provide some extra information when declaring certain kinds of external variables, that are bound by the host/API side.
Descriptor set/binding annotations #
UBOs, SSBOs and texturing resources need to be annotated with descriptor_binding()
and descriptor_set()
:
descriptor_set(0) descriptor_binding(1)
uniform int my_funny_buffer[256];
Shader I/O #
Similar to recent versions of GLSL, input
and output
variables need to provide a location(N)
:
location(0)
input vec2 texCoord;
location(0)
output vec4 pixelColor;
See the following list of address soaces
Address spaces #
LLVM and Clang already support address spaces using the __attribute__((address_space(N)))
syntax. Shady merely reserves some numbers for custom address spaces, and tries to line up with other targets where possible.
Vcc keyword | SPIR-V Storage class | Purpose |
---|---|---|
input |
Input |
Pipeline-specific inputs |
output |
Output |
Pipeline-specific outputs |
uniform_constant |
UniformConstant |
Most opaque descriptor-bound resources (samplers, textures, …) |
uniform_block |
Uniform |
Vulkan UBOs |
shared |
Workgroup |
Workgroup-visible local memory |
private |
Private / Function |
Invocation private memory |
global |
PhysicalStorageBuffer |
Main memory (VRAM and mapped host memory) |
While Shady supports generic pointers, only private
, shared
and global
will be able to work with them. There are many more address spaces found in SPIR-V that have usage restrictions that make them pointless to support in generic pointers, and therefore those need to be explicitly specified.
This is also true for global variables: while you can get a generic pointer to them (just cast it!), the variables do need to be allocated somewhere !