summaryrefslogtreecommitdiffstats
path: root/examples/reflection-parameter-blocks/common.slang
blob: d8f81224605b0004ca27f2a78c7010e1dedf8e69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// shader.slang

// This module is part of the `reflection-parameter-blocks`
// example program.
//
// This module is split out from the files that define
// individual programs, so that we can share some type
// definitions and utility functions between all of
// the programs and keep them focused on just defining
// the shader entry points.

struct Mesh
{
    float4x4 modelToWorld;
    float4x4 modelToWorld_inverseTranspose;
}

struct Material
{
    Texture2D albedoMap;
    Texture2D glossMap;
    Texture2D normalMap;
    SamplerState sampler;
}

interface ILight
{
}

struct DirectionalLight : ILight
{
    float3 dir;
    float3 intensity;
}

struct ShadowedLight<L : ILight> : ILight
{
    L light;
    Texture2D shadowMap;
    SamplerComparisonState shadowSampler;
    float4x4 worldToShadow;
}

struct EnvironmentMap
{
    TextureCube texture;
    SamplerState sampler;
}

struct Environment
{
    ShadowedLight<DirectionalLight> sunLight;
    EnvironmentMap envMap;
    RWStructuredBuffer<float4> output;
}

struct View
{
    float4x4 worldToView;
    float4x4 viewToProj;
}

// While the Slang compilation library will *reflect* all of
// the shader parameters that a program declares,
// back-ends (such as the SPIR-V code generator) will often
// strip out parameters that are not used as part of the
// computation that a shader performs.
//
// When shader parameters are stripped from the output
// binary code, the runtime system for a particular API
// (e.g., the Vulkan validation layer) cannot check
// whether a program is correctly handling the binding
// of those parameters.
//
// Our example entry points will thus make use of some
// utility routines that serve the purpose of allowing
// us to ensure that specific parameters are seen as
// "used" during code generation.

void use(inout float4 r, float4 v) { r += v; }
void use(inout float4 r, float3 v) { r.xyz += v; }

void use(inout float4 r, Texture2D t, SamplerState s)
{
    use(r, t.SampleLevel(s, r.xy, 0));
}

void use(inout float4 r, RWStructuredBuffer<float4> b)
{
    use(r, b[int(r.x)]);
    b[int(r.x)] = r;
}

void use(inout float4 r, Environment e)
{
    use(r, e.sunLight.light.dir);
    use(r, e.output);
}

void use(inout float4 r, View v)
{
    use(r, v.worldToView[0]);
}

void use(inout float4 r, Material m)
{
    use(r, m.normalMap, m.sampler);
}

void use(inout float4 r, Mesh m)
{
    use(r, m.modelToWorld[0]);
}