1
1
const std = @import ("std.zig" );
2
2
3
- /// Will make `ptr` contain the location of the current invocation within the
4
- /// global workgroup. Each component is equal to the index of the local workgroup
5
- /// multiplied by the size of the local workgroup plus `localInvocationId`.
6
- /// `ptr` must be a reference to variable or struct field.
7
- pub fn globalInvocationId (comptime ptr : * addrspace (.input ) @Vector (3 , u32 )) void {
8
- asm volatile (
9
- \\OpDecorate %ptr BuiltIn GlobalInvocationId
10
- :
11
- : [ptr ] "" (ptr ),
12
- );
13
- }
14
-
15
- /// Will make that variable contain the location of the current cluster
16
- /// culling, task, mesh, or compute shader invocation within the local
17
- /// workgroup. Each component ranges from zero through to the size of the
18
- /// workgroup in that dimension minus one.
19
- /// `ptr` must be a reference to variable or struct field.
20
- pub fn localInvocationId (comptime ptr : * addrspace (.input ) @Vector (3 , u32 )) void {
21
- asm volatile (
22
- \\OpDecorate %ptr BuiltIn LocalInvocationId
23
- :
24
- : [ptr ] "" (ptr ),
25
- );
26
- }
27
-
28
- /// Output vertex position from a `Vertex` entrypoint
29
- /// `ptr` must be a reference to variable or struct field.
30
- pub fn position (comptime ptr : * addrspace (.output ) @Vector (4 , f32 )) void {
31
- asm volatile (
32
- \\OpDecorate %ptr BuiltIn Position
33
- :
34
- : [ptr ] "" (ptr ),
35
- );
36
- }
37
-
38
- /// Will make `ptr` contain the index of the vertex that is
39
- /// being processed by the current vertex shader invocation.
40
- /// `ptr` must be a reference to variable or struct field.
41
- pub fn vertexIndex (comptime ptr : * addrspace (.input ) u32 ) void {
42
- asm volatile (
43
- \\OpDecorate %ptr BuiltIn VertexIndex
44
- :
45
- : [ptr ] "" (ptr ),
46
- );
47
- }
48
-
49
- /// Will make `ptr` contain the index of the instance that is
50
- /// being processed by the current vertex shader invocation.
51
- /// `ptr` must be a reference to variable or struct field.
52
- pub fn instanceIndex (comptime ptr : * addrspace (.input ) u32 ) void {
53
- asm volatile (
54
- \\OpDecorate %ptr BuiltIn InstanceIndex
55
- :
56
- : [ptr ] "" (ptr ),
57
- );
58
- }
59
-
60
- /// Output fragment depth from a `Fragment` entrypoint
61
- /// `ptr` must be a reference to variable or struct field.
62
- pub fn fragmentCoord (comptime ptr : * addrspace (.input ) @Vector (4 , f32 )) void {
63
- asm volatile (
64
- \\OpDecorate %ptr BuiltIn FragCoord
65
- :
66
- : [ptr ] "" (ptr ),
67
- );
68
- }
69
-
70
- /// Output fragment depth from a `Fragment` entrypoint
71
- /// `ptr` must be a reference to variable or struct field.
72
- pub fn fragmentDepth (comptime ptr : * addrspace (.output ) f32 ) void {
73
- asm volatile (
74
- \\OpDecorate %ptr BuiltIn FragDepth
75
- :
76
- : [ptr ] "" (ptr ),
77
- );
78
- }
3
+ pub const position_in = @extern (* addrspace (.input ) @Vector (4 , f32 ), .{ .name = "position" });
4
+ pub const position_out = @extern (* addrspace (.output ) @Vector (4 , f32 ), .{ .name = "position" });
5
+ pub const point_size_in = @extern (* addrspace (.input ) f32 , .{ .name = "point_size" });
6
+ pub const point_size_out = @extern (* addrspace (.output ) f32 , .{ .name = "point_size" });
7
+ pub extern const invocation_id : u32 addrspace (.input );
8
+ pub extern const frag_coord : @Vector (4 , f32 ) addrspace (.input );
9
+ pub extern const point_coord : @Vector (2 , f32 ) addrspace (.input );
10
+ // TODO: direct/indirect values
11
+ // pub extern const front_facing: bool addrspace(.input);
12
+ // TODO: runtime array
13
+ // pub extern const sample_mask;
14
+ pub extern var frag_depth : f32 addrspace (.output );
15
+ pub extern const num_workgroups : @Vector (3 , u32 ) addrspace (.input );
16
+ pub extern const workgroup_size : @Vector (3 , u32 ) addrspace (.input );
17
+ pub extern const workgroup_id : @Vector (3 , u32 ) addrspace (.input );
18
+ pub extern const local_invocation_id : @Vector (3 , u32 ) addrspace (.input );
19
+ pub extern const global_invocation_id : @Vector (3 , u32 ) addrspace (.input );
20
+ pub extern const vertex_index : u32 addrspace (.input );
21
+ pub extern const instance_index : u32 addrspace (.input );
79
22
80
23
/// Forms the main linkage for `input` and `output` address spaces.
81
24
/// `ptr` must be a reference to variable or struct field.
@@ -101,74 +44,85 @@ pub fn binding(comptime ptr: anytype, comptime set: u32, comptime bind: u32) voi
101
44
);
102
45
}
103
46
104
- pub const Origin = enum (u32 ) {
105
- /// Increase toward the right and downward
106
- upper_left = 7 ,
107
- /// Increase toward the right and upward
108
- lower_left = 8 ,
109
- };
110
-
111
- /// The coordinates appear to originate in the specified `origin`.
112
- /// Only valid with the `Fragment` calling convention.
113
- pub fn fragmentOrigin (comptime entry_point : anytype , comptime origin : Origin ) void {
114
- asm volatile (
115
- \\OpExecutionMode %entry_point $origin
116
- :
117
- : [entry_point ] "" (entry_point ),
118
- [origin ] "c" (@intFromEnum (origin )),
119
- );
120
- }
121
-
122
- pub const DepthMode = enum (u32 ) {
123
- /// Declares that this entry point dynamically writes the
124
- /// `fragmentDepth` built in-decorated variable.
125
- replacing = 12 ,
47
+ pub const ExecutionMode = union (Tag ) {
48
+ /// Sets origin of the framebuffer to the upper-left corner
49
+ origin_upper_left ,
50
+ /// Sets origin of the framebuffer to the lower-left corner
51
+ origin_lower_left ,
52
+ /// Indicates that the fragment shader writes to `frag_depth`,
53
+ /// replacing the fixed-function depth value.
54
+ depth_replacing ,
126
55
/// Indicates that per-fragment tests may assume that
127
- /// any `fragmentDepth ` built in-decorated value written by the shader is
56
+ /// any `frag_depth ` built in-decorated value written by the shader is
128
57
/// greater-than-or-equal to the fragment’s interpolated depth value
129
- greater = 14 ,
58
+ depth_greater ,
130
59
/// Indicates that per-fragment tests may assume that
131
- /// any `fragmentDepth ` built in-decorated value written by the shader is
60
+ /// any `frag_depth ` built in-decorated value written by the shader is
132
61
/// less-than-or-equal to the fragment’s interpolated depth value
133
- less = 15 ,
62
+ depth_less ,
134
63
/// Indicates that per-fragment tests may assume that
135
- /// any `fragmentDepth ` built in-decorated value written by the shader is
64
+ /// any `frag_depth ` built in-decorated value written by the shader is
136
65
/// the same as the fragment’s interpolated depth value
137
- unchanged = 16 ,
138
- };
66
+ depth_unchanged ,
67
+ /// Indicates the workgroup size in the x, y, and z dimensions.
68
+ local_size : LocalSize ,
139
69
140
- /// Only valid with the `Fragment` calling convention.
141
- pub fn depthMode ( comptime entry_point : anytype , comptime mode : DepthMode ) void {
142
- asm volatile (
143
- \\OpExecutionMode %entry_point $mode
144
- :
145
- : [ entry_point ] "" ( entry_point ) ,
146
- [ mode ] "c" ( mode ) ,
147
- );
148
- }
70
+ pub const Tag = enum ( u32 ) {
71
+ origin_upper_left = 7 ,
72
+ origin_lower_left = 8 ,
73
+ depth_replacing = 12 ,
74
+ depth_greater = 14 ,
75
+ depth_less = 15 ,
76
+ depth_unchanged = 16 ,
77
+ local_size = 17 ,
78
+ };
149
79
150
- /// Indicates the workgroup size in the `x`, `y`, and `z` dimensions.
151
- /// Only valid with the `GLCompute` or `Kernel` calling conventions.
152
- pub fn workgroupSize (comptime entry_point : anytype , comptime size : @Vector (3 , u32 )) void {
153
- asm volatile (
154
- \\OpExecutionMode %entry_point LocalSize %x %y %z
155
- :
156
- : [entry_point ] "" (entry_point ),
157
- [x ] "c" (size [0 ]),
158
- [y ] "c" (size [1 ]),
159
- [z ] "c" (size [2 ]),
160
- );
161
- }
80
+ pub const LocalSize = struct { x : u32 , y : u32 , z : u32 };
81
+ };
162
82
163
- /// A hint to the client, which indicates the workgroup size in the `x`, `y`, and `z` dimensions.
164
- /// Only valid with the `GLCompute` or `Kernel` calling conventions.
165
- pub fn workgroupSizeHint (comptime entry_point : anytype , comptime size : @Vector (3 , u32 )) void {
166
- asm volatile (
167
- \\OpExecutionMode %entry_point LocalSizeHint %x %y %z
168
- :
169
- : [entry_point ] "" (entry_point ),
170
- [x ] "c" (size [0 ]),
171
- [y ] "c" (size [1 ]),
172
- [z ] "c" (size [2 ]),
173
- );
83
+ /// Declare the mode entry point executes in.
84
+ pub fn executionMode (comptime entry_point : anytype , comptime mode : ExecutionMode ) void {
85
+ const cc = @typeInfo (@TypeOf (entry_point )).@"fn" .calling_convention ;
86
+ switch (mode ) {
87
+ .origin_upper_left ,
88
+ .origin_lower_left ,
89
+ .depth_replacing ,
90
+ .depth_greater ,
91
+ .depth_less ,
92
+ .depth_unchanged ,
93
+ = > {
94
+ if (cc != .spirv_fragment ) {
95
+ @compileError (
96
+ \\invalid execution mode '
97
+ ++ @tagName (mode ) ++
98
+ \\' for function with '
99
+ ++ @tagName (cc ) ++
100
+ \\' calling convention
101
+ );
102
+ }
103
+ asm volatile (
104
+ \\OpExecutionMode %entry_point $mode
105
+ :
106
+ : [entry_point ] "" (entry_point ),
107
+ [mode ] "c" (@intFromEnum (mode )),
108
+ );
109
+ },
110
+ .local_size = > | size | {
111
+ if (cc != .spirv_kernel ) {
112
+ @compileError (
113
+ \\invalid execution mode 'local_size' for function with '
114
+ ++ @tagName (cc ) ++
115
+ \\' calling convention
116
+ );
117
+ }
118
+ asm volatile (
119
+ \\OpExecutionMode %entry_point LocalSize $x $y $z
120
+ :
121
+ : [entry_point ] "" (entry_point ),
122
+ [x ] "c" (size .x ),
123
+ [y ] "c" (size .y ),
124
+ [z ] "c" (size .z ),
125
+ );
126
+ },
127
+ }
174
128
}
0 commit comments