Skip to content

Latest commit

 

History

History
210 lines (161 loc) · 6.2 KB

File metadata and controls

210 lines (161 loc) · 6.2 KB

API Reference: Kernels

Purpose

Kernel APIs define generated compute shader shapes and shader-only runtime markers such as thread IDs, barriers, shared memory, and atomics.

Kernel Shape

[Kernel]
[ThreadGroupSize(DefaultThreadGroupSizes.X)]
public readonly partial struct MyKernel(ReadWriteBuffer<float> data) : IKernel1D
{
    public void Execute()
    {
        int i = ThreadIds.X;
        data[i] = data[i] + 1.0f;
    }
}
Interface Dispatch size Thread ID helper
IKernel1D int ThreadIds.X
IKernel2D int2 ThreadIds.XY
IKernel3D int3 ThreadIds.XYZ

Thread And Group IDs

API Meaning
ThreadIds.X/Y/Z Global invocation components.
ThreadIds.XY/XYZ Global invocation vectors.
LocalIds.X/Y/Z Local workgroup invocation components.
GroupIds.X/Y/Z Workgroup ID components.
DispatchSize.X/Y/Z Logical dispatch size.
GroupSize.X/Y/Z Declared local group size.

These properties are shader-only markers and throw on the CPU.

Dispatch

GPU.Dispatch(new Kernel1D(...), count);
GPU.Dispatch(new Kernel2D(...), new int2(width, height));
GPU.Dispatch(new Kernel3D(...), new int3(width, height, depth));

DispatchPath path = GPU.DispatchAndGetPath(new Kernel1D(...), count);

wait defaults to true. Use DispatchAndGetPath in samples and tests when you need to prove the native route.

Callables

Kernel-local helper:

[Callable]
private static float Smooth(float x)
{
    return x * x * (3.0f - (2.0f * x));
}

Reusable helper library:

[ShaderLibrary]
public static class Brdf
{
    [Callable]
    public static float3 Diffuse(float3 albedo, float nDotL)
    {
        return albedo * ShaderMath.Clamp(nDotL, 0.0f, 1.0f);
    }
}

Callables must use supported shader value types. Overloads bind by generated symbol identity. [ShaderLibrary] callables must be static and source-available to the consuming compilation.

[GpuStruct] instance callables are supported. Feather lowers the receiver as an explicit first parameter. Read-only receiver methods use an in parameter. Methods that assign to this or a nested receiver field use an inout receiver, so calls on locals and ReadWriteBuffer<T> elements can write back through the original l-value.

[GpuStruct]
public partial struct Counter
{
    public float Value;

    [Callable]
    public void Add(float amount)
    {
        Value += amount;
    }
}

Mutating receiver calls require an addressable receiver. A call on a temporary value, or on an element from a read-only resource, is rejected by the generator.

Generic Interface Callables

Shader callables may use generic type parameters when every use can be monomorphized from concrete GPU value types. The supported object-style pattern is an interface constraint implemented by [GpuStruct] types:

public interface IShape
{
    float Sdf(float3 p);
}

[GpuStruct]
public readonly partial record struct Sphere(float Radius) : IShape
{
    [Callable]
    public float Sdf(float3 p) => ShaderMath.Length(p) - Radius;
}

[ShaderLibrary]
public static class ShapeOps
{
    [Callable]
    public static float Eval<TShape>(TShape shape, float3 p)
        where TShape : IShape
    {
        return shape.Sdf(p);
    }
}

Each concrete call, such as Eval<Sphere>, emits a separate callable and directly calls Sphere.Sdf. Feather does not lower interface-typed locals, virtual dispatch, reference identity, vtables, or class inheritance into GPU code.

Shared Memory

var shared = new SharedMemory<float>(256);
shared[LocalIds.X] = input[ThreadIds.X];
GpuBarrier.Workgroup();
output[ThreadIds.X] = shared[LocalIds.X];

SharedMemory<T> is shader-only and intended for workgroup-local scratch storage.

Barriers

API Purpose
GpuBarrier.Workgroup() Workgroup execution/memory barrier.
GpuBarrier.Memory() Memory barrier.
GpuBarrier.Full() Combined barrier.

Barriers are shader markers and throw if called on the CPU.

Atomics

Integer atomics operate on supported l-values:

GpuAtomic.Add(ref counters[0], 1);
GpuAtomic.CompareExchange(ref values[i], expected, replacement);
API Operation
Add Atomic add.
Sub Atomic subtract.
Min / Max Atomic min/max.
And / Or / Xor Atomic bitwise operations.
Exchange Atomic exchange.
CompareExchange Atomic compare-exchange.

Generated Kernel Objects

Most code uses GPU.Dispatch. GpuKernel is available for lower-level inspection and dispatch:

API Purpose
GpuKernel.Create<TKernel>(context) Creates a native kernel object.
GpuKernel.Dispatch(...) Dispatches with an explicit context/kernel object.
GetGLSL() Returns unoptimized GLSL.
GetOptimizedGLSL() Returns backend-optimized GLSL inspection text.
LastDispatchPath Last native route.

Related Docs

Host Vs Shader

  • GPU.Dispatch and GpuKernel are host APIs.
  • ThreadIds, LocalIds, GroupIds, DispatchSize, GroupSize, GpuBarrier, GpuAtomic, and SharedMemory<T> are shader-only markers.
  • [Callable] methods are ordinary C# declarations at compile time, but their bodies must fit the shader subset.
  • [ShaderLibrary] is a compile-time import marker; it does not register runtime functions.
  • Generic interface callables are compile-time monomorphization only; runtime interface dispatch remains unsupported.

Lifetime And Errors

  • GpuKernel is disposable when you create one explicitly.
  • Most applications use GPU.Dispatch, which creates and releases native kernel state for that dispatch.
  • Shader-only marker APIs throw when called on the CPU.
  • Unsupported statements/calls produce generator diagnostics before dispatch.

Samples And Tests

  • samples/HelloBuffer
  • samples/GpuStructInterfaces
  • samples/ParallelReduction
  • samples/Histogram
  • tests/Feather.Integration.Tests/GeneratedComputeDispatchTests.cs
  • tests/Feather.Integration.Tests/ShaderDslCoverageTests.cs