Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shader #8

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,7 @@ pub const Cpu = struct {
.fs, .gs, .ss => arch == .x86_64 or arch == .x86,
.global, .constant, .local, .shared => is_gpu,
.param => is_nvptx,
.input, .output, .uniform => is_spirv,
// TODO this should also check how many flash banks the cpu has
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
};
Expand Down Expand Up @@ -2353,7 +2354,7 @@ pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
.longdouble => return 128,
},

.opencl => switch (c_type) {
.opencl, .vulkan => switch (c_type) {
.char => return 8,
.short, .ushort => return 16,
.int, .uint, .float => return 32,
Expand Down Expand Up @@ -2386,7 +2387,6 @@ pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
.hermit,
.hurd,
.glsl450,
.vulkan,
.driverkit,
.shadermodel,
.liteos,
Expand Down
6 changes: 6 additions & 0 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ pub const CallingConvention = enum(u8) {
Win64,
/// AMD GPU, NVPTX, or SPIR-V kernel
Kernel,
// Vulkan-only
Fragment,
Vertex,
};

/// This data structure is used by the Zig language code generation and
Expand All @@ -222,6 +225,9 @@ pub const AddressSpace = enum(u5) {
param,
shared,
local,
input,
output,
uniform,
alichraghi marked this conversation as resolved.
Show resolved Hide resolved

// AVR address spaces.
flash,
Expand Down
166 changes: 166 additions & 0 deletions lib/std/gpu.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
const std = @import("std.zig");
const comptimePrint = std.fmt.comptimePrint;

/// Will make `ptr` contain the location of the current invocation within the
/// global workgroup. Each component is equal to the index of the local workgroup
/// multiplied by the size of the local workgroup plus `localInvocationId`.
/// `ptr` must be a reference to variable or struct field.
pub fn globalInvocationId(comptime ptr: *addrspace(.input) @Vector(3, u32)) void {
asm volatile (
\\OpDecorate %ptr BuiltIn GlobalInvocationId
:
: [ptr] "" (ptr),
);
}

/// Will make that variable contain the location of the current cluster
/// culling, task, mesh, or compute shader invocation within the local
/// workgroup. Each component ranges from zero through to the size of the
/// workgroup in that dimension minus one.
/// `ptr` must be a reference to variable or struct field.
pub fn localInvocationId(comptime ptr: *addrspace(.input) @Vector(3, u32)) void {
asm volatile (
\\OpDecorate %ptr BuiltIn LocalInvocationId
:
: [ptr] "" (ptr),
);
}

/// Output vertex position from a `Vertex` entrypoint
/// `ptr` must be a reference to variable or struct field.
pub fn position(comptime ptr: *addrspace(.output) @Vector(4, f32)) void {
asm volatile (
\\OpDecorate %ptr BuiltIn Position
:
: [ptr] "" (ptr),
);
}

/// Will make `ptr` contain the index of the vertex that is
/// being processed by the current vertex shader invocation.
/// `ptr` must be a reference to variable or struct field.
pub fn vertexIndex(comptime ptr: *addrspace(.input) u32) void {
asm volatile (
\\OpDecorate %ptr BuiltIn VertexIndex
:
: [ptr] "" (ptr),
);
}

/// Output fragment depth from a `Fragment` entrypoint
/// `ptr` must be a reference to variable or struct field.
pub fn fragmentCoord(comptime ptr: *addrspace(.input) @Vector(4, f32)) void {
asm volatile (
\\OpDecorate %ptr BuiltIn FragCoord
:
: [ptr] "" (ptr),
);
}

/// Output fragment depth from a `Fragment` entrypoint
/// `ptr` must be a reference to variable or struct field.
pub fn fragmentDepth(comptime ptr: *addrspace(.output) f32) void {
asm volatile (
\\OpDecorate %ptr BuiltIn FragDepth
:
: [ptr] "" (ptr),
);
}

/// Forms the main linkage for `input` and `output` address spaces.
/// `ptr` must be a reference to variable or struct field.
pub fn location(comptime ptr: anytype, comptime loc: u32) void {
const code = comptimePrint("OpDecorate %ptr Location {}", .{loc});
asm volatile (code
:
: [ptr] "" (ptr),
);
}

/// Forms the main linkage for `input` and `output` address spaces.
/// `ptr` must be a reference to variable or struct field.
pub fn binding(comptime ptr: anytype, comptime group: u32, comptime bind: u32) void {
const code = comptimePrint(
\\OpDecorate %ptr DescriptorSet {}
\\OpDecorate %ptr Binding {}
, .{ group, bind });
asm volatile (code
:
: [ptr] "" (ptr),
);
Snektron marked this conversation as resolved.
Show resolved Hide resolved
}

pub const Origin = enum(u32) {
/// Increase toward the right and downward
upper_left = 7,
/// Increase toward the right and upward
lower_left = 8,
};

/// The coordinates appear to originate in the specified `origin`.
/// Only valid with the `Fragment` calling convention.
pub fn fragmentOrigin(comptime entry_point: anytype, comptime origin: Origin) void {
const origin_enum = switch (origin) {
.upper_left => .OriginUpperLeft,
.lower_left => .OriginLowerLeft,
};
asm volatile ("OpExecutionMode %entry_point " ++ @tagName(origin_enum)
:
: [entry_point] "" (entry_point),
);
}

pub const DepthMode = enum(u32) {
/// Declares that this entry point dynamically writes the
/// `fragmentDepth` built in-decorated variable.
replacing = 12,
/// Indicates that per-fragment tests may assume that
/// any `fragmentDepth` built in-decorated value written by the shader is
/// greater-than-or-equal to the fragment’s interpolated depth value
greater = 14,
/// Indicates that per-fragment tests may assume that
/// any `fragmentDepth` built in-decorated value written by the shader is
/// less-than-or-equal to the fragment’s interpolated depth value
less = 15,
/// Indicates that per-fragment tests may assume that
/// any `fragmentDepth` built in-decorated value written by the shader is
/// the same as the fragment’s interpolated depth value
unchanged = 16,
};

/// Only valid with the `Fragment` calling convention.
pub fn depthMode(comptime entry_point: anytype, comptime mode: DepthMode) void {
const code = comptimePrint("OpExecutionMode %entry_point {}", .{@intFromEnum(mode)});
asm volatile (code
:
: [entry_point] "" (entry_point),
);
}

/// Indicates the workgroup size in the `x`, `y`, and `z` dimensions.
/// Only valid with the `GLCompute` or `Kernel` calling conventions.
pub fn workgroupSize(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void {
const code = comptimePrint("OpExecutionMode %entry_point LocalSize {} {} {}", .{
size[0],
size[1],
size[2],
});
asm volatile (code
:
: [entry_point] "" (entry_point),
);
}

/// A hint to the client, which indicates the workgroup size in the `x`, `y`, and `z` dimensions.
/// Only valid with the `GLCompute` or `Kernel` calling conventions.
pub fn workgroupSizeHint(comptime entry_point: anytype, comptime size: @Vector(3, u32)) void {
const code = comptimePrint("OpExecutionMode %entry_point LocalSizeHint {} {} {}", .{
size[0],
size[1],
size[2],
});
asm volatile (code
:
: [entry_point] "" (entry_point),
);
}
3 changes: 3 additions & 0 deletions lib/std/std.zig
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ pub const fmt = @import("fmt.zig");
/// File system-related functionality.
pub const fs = @import("fs.zig");

/// GPU programming helpers.
pub const gpu = @import("gpu.zig");

/// Fast hashing functions (i.e. not cryptographically secure).
pub const hash = @import("hash.zig");
pub const hash_map = @import("hash_map.zig");
Expand Down
5 changes: 5 additions & 0 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9741,6 +9741,10 @@ fn finishFunc(
.nvptx, .nvptx64, .amdgcn, .spirv32, .spirv64 => null,
else => "nvptx, amdgcn and SPIR-V",
},
.Fragment, .Vertex => switch (arch) {
.spirv32, .spirv64 => null,
else => "SPIR-V",
},
})) |allowed_platform| {
return sema.fail(block, cc_src, "callconv '{s}' is only available on {s}, not {s}", .{
@tagName(cc_resolved),
Expand Down Expand Up @@ -37916,6 +37920,7 @@ pub fn analyzeAddressSpace(
.gs, .fs, .ss => (arch == .x86 or arch == .x86_64) and ctx == .pointer,
// TODO: check that .shared and .local are left uninitialized
.param => is_nv,
.input, .output, .uniform => is_spirv,
.global, .shared, .local => is_gpu,
.constant => is_gpu and (ctx == .constant),
// TODO this should also check how many flash banks the cpu has
Expand Down
1 change: 1 addition & 0 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10848,6 +10848,7 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) Builder
.amdgcn => .amdgpu_kernel,
else => unreachable,
},
.Vertex, .Fragment => unreachable,
};
}

Expand Down
Loading
Loading