updated spng, theoratest, spng, tracy
This commit is contained in:
parent
de6ccd211b
commit
d738dd2260
|
|
@ -1,2 +0,0 @@
|
||||||
zig-cache/
|
|
||||||
zig-out/
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# spirv-reflect-zig
|
|
||||||
|
|
||||||
This is a small program meant to reflect out zig compatible data structures from compiled spirv modules.
|
|
||||||
You can use the program in standalone or use it as part of your build.zig build system.
|
|
||||||
|
|
||||||
|
|
||||||
## As part of a build system
|
|
||||||
|
|
||||||
```zig
|
|
||||||
var spirvCompile = SpirvGenerator.init(b, .{.target = target, .optimize = optimize, .repoPath = "src"});
|
|
||||||
var myShader = spirvCompile.shader("path/to/shader.glsl", "myShader");
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
myExe.addModule("myShaderTypes", myShader);
|
|
||||||
```
|
|
||||||
|
|
||||||
In your program you can now access all the types defined in the shader
|
|
||||||
from your zig program via a simple zig import
|
|
||||||
|
|
||||||
```zig
|
|
||||||
const myShaderTypes = @import("myShaderTypes");
|
|
||||||
const ImageRenderData = myShaderTypes.ImageRenderData; // ImageRenderData conforms to the data layout specified
|
|
||||||
const gl = myShaderTypes.gl; // glsl base types are available through this node in the module
|
|
||||||
```
|
|
||||||
|
|
||||||
```zig
|
|
||||||
|
|
||||||
var mappedBuffer = SomeGpuApi.mapBuffer(...);
|
|
||||||
|
|
||||||
var typedBuffer = @ptrCast([*]ImageRenderData, mappedBuffer);
|
|
||||||
typedBuffer[0] = .{.someXYField = gl.vec2{.x = 42, .y = 42} };
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## As a standalone CLI
|
|
||||||
|
|
||||||
You can generate the standalone CLI from this folder by calling `zig build install`.
|
|
||||||
|
|
||||||
This will create `spirv-reflect-zig` in `zig-out/bin`. This will be able to reflect the
|
|
||||||
contents of a json file generated by `spirv-cross --reflect` into a .zig file
|
|
||||||
|
|
||||||
`spirv-cross myshader.glsl --reflect --output myshader.json &&\
|
|
||||||
spirv-reflect-zig myshader.json -o myshader.zig`
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const Build = std.Build;
|
|
||||||
const LazyPath = Build.LazyPath;
|
|
||||||
|
|
||||||
// 1. for each vertex/fragment shader file invoke
|
|
||||||
// glslc --target-env=vulkan1.2 <input file> -o <input file>.spv
|
|
||||||
//
|
|
||||||
// 2. for each generated .spv file i want to invoke
|
|
||||||
// spirv-cross --reflect <input file>.spv --output <input file>.json
|
|
||||||
//
|
|
||||||
// 3. compile the reflect program, and invoke it on the json file.
|
|
||||||
// spirv-reflect-zig <input file>.json
|
|
||||||
//
|
|
||||||
// <input file>.zig
|
|
||||||
|
|
||||||
pub const SpirvGenerator2 = struct {
|
|
||||||
b: *Build,
|
|
||||||
spirv_build: *Build,
|
|
||||||
glslTypes: *Build.Module,
|
|
||||||
|
|
||||||
reflect: *Build.Step.Compile,
|
|
||||||
|
|
||||||
const BuildOptions = struct {
|
|
||||||
importName: []const u8 = "SpirvReflect",
|
|
||||||
optimize: std.builtin.OptimizeMode = .Debug,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn initFromBuilder(b: *Build, spirv_build: *Build, opts: BuildOptions) SpirvGenerator2 {
|
|
||||||
const reflect = spirv_build.addExecutable(.{
|
|
||||||
.name = "spirv-reflect-zig",
|
|
||||||
.root_source_file = spirv_build.path("src/main.zig"),
|
|
||||||
.target = spirv_build.graph.host,
|
|
||||||
.optimize = opts.optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const dep = spirv_build.dependency("glslTypes", .{
|
|
||||||
.target = spirv_build.graph.host,
|
|
||||||
.optimize = opts.optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
return .{
|
|
||||||
.b = b,
|
|
||||||
.spirv_build = spirv_build,
|
|
||||||
.reflect = reflect,
|
|
||||||
.glslTypes = dep.module("glslTypes"),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(b: *Build, opts: BuildOptions) SpirvGenerator2 {
|
|
||||||
const dep = b.dependency(opts.importName, .{});
|
|
||||||
return initFromBuilder(b, dep.builder, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn createShader(
|
|
||||||
self: SpirvGenerator2,
|
|
||||||
shaderPath: Build.LazyPath,
|
|
||||||
shaderName: []const u8,
|
|
||||||
) struct { mod: *Build.Module, spvArtifactInstall: *Build.Step } {
|
|
||||||
const importSpv = self.b.fmt("{s}.spv", .{shaderName});
|
|
||||||
const finalSpv = self.b.fmt("shaders/{s}.spv", .{shaderName});
|
|
||||||
const finalJson = self.b.fmt("shaders/{s}.json", .{shaderName});
|
|
||||||
const finalZig = self.b.fmt("reflectedTypes/{s}.zig", .{shaderName});
|
|
||||||
|
|
||||||
const shaderCompile = self.b.addSystemCommand(&[_][]const u8{"glslc"});
|
|
||||||
shaderCompile.addFileArg(shaderPath);
|
|
||||||
shaderCompile.addArg("--target-env=vulkan1.2");
|
|
||||||
shaderCompile.addArg("-o");
|
|
||||||
const spvOutputFile = shaderCompile.addOutputFileArg(finalSpv);
|
|
||||||
|
|
||||||
const spvOutputArtifact = self.b.addInstallFile(spvOutputFile, finalSpv);
|
|
||||||
|
|
||||||
const jsonReflectStep = self.spirv_build.addSystemCommand(&[_][]const u8{"spirv-cross"});
|
|
||||||
jsonReflectStep.addFileArg(spvOutputFile);
|
|
||||||
jsonReflectStep.addArg("--reflect");
|
|
||||||
jsonReflectStep.addArg("--output");
|
|
||||||
const outputJson = jsonReflectStep.addOutputFileArg(finalJson);
|
|
||||||
|
|
||||||
const run_cmd = self.b.addRunArtifact(self.reflect);
|
|
||||||
run_cmd.addFileArg(outputJson);
|
|
||||||
run_cmd.addArg("-e");
|
|
||||||
run_cmd.addArg(importSpv);
|
|
||||||
run_cmd.addArg("-o");
|
|
||||||
const outputZigFile = run_cmd.addOutputFileArg(finalZig);
|
|
||||||
|
|
||||||
const module = self.spirv_build.createModule(.{
|
|
||||||
.root_source_file = outputZigFile,
|
|
||||||
});
|
|
||||||
|
|
||||||
module.addAnonymousImport(importSpv, .{
|
|
||||||
.root_source_file = spvOutputFile,
|
|
||||||
});
|
|
||||||
|
|
||||||
module.addImport("glslTypes", self.glslTypes);
|
|
||||||
|
|
||||||
return .{ .mod = module, .spvArtifactInstall = &spvOutputArtifact.step };
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a shader and immediately adds it to the executable
|
|
||||||
pub fn addShader(
|
|
||||||
self: SpirvGenerator2,
|
|
||||||
module: *Build.Module,
|
|
||||||
shaderPath: LazyPath,
|
|
||||||
shaderName: []const u8,
|
|
||||||
) void {
|
|
||||||
const results = self.createShader(shaderPath, shaderName);
|
|
||||||
module.addImport(shaderName, results.mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addShaderInstallRef(self: *SpirvGenerator2, exe: *Build.Step.Compile, shader_path: LazyPath, shader_name: []const u8) void {
|
|
||||||
const results = self.createShader(shader_path, shader_name);
|
|
||||||
exe.step.dependOn(results.spvArtifactInstall);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
|
||||||
_ = static_build;
|
|
||||||
|
|
||||||
const test_step = b.step("test", "");
|
|
||||||
const tests = b.addTest(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.root_source_file = b.path("src/test.zig"),
|
|
||||||
.link_libc = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
|
||||||
test_step.dependOn(&runArtifact.step);
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
.{
|
|
||||||
.name = .SpirvReflect,
|
|
||||||
.version = "0.0.0",
|
|
||||||
.dependencies = .{
|
|
||||||
.glslTypes = .{ .path = "glslTypes" },
|
|
||||||
},
|
|
||||||
.paths = .{
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
.fingerprint = 0x8bdf68352d7dc5fa,
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const SpirvReflect = @import("SpirvReflect");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const spirvGen = SpirvReflect.SpirvGenerator2.init(b, .{});
|
|
||||||
b.installArtifact(spirvGen.reflect);
|
|
||||||
|
|
||||||
const test_vk = spirvGen.createShader(.{ .path = "../shaders/test_vk.vert" }, "test_vk");
|
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
|
||||||
.name = "example",
|
|
||||||
.root_source_file = .{ .path = "main.zig" },
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
exe.root_module.addImport("test_vk", test_vk);
|
|
||||||
spirvGen.addShader(&exe.root_module, "../shaders/test_vk.vert", "test_vk2");
|
|
||||||
|
|
||||||
b.installArtifact(exe);
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
.{
|
|
||||||
.name = "testing",
|
|
||||||
.version = "0.0.0",
|
|
||||||
|
|
||||||
.dependencies = .{
|
|
||||||
.SpirvReflect = .{ .path = "../" },
|
|
||||||
},
|
|
||||||
|
|
||||||
.paths = .{
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const test_vk = @import("test_vk");
|
|
||||||
const test_vk2 = @import("test_vk2");
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
std.debug.print("hello world {d}\n", .{@sizeOf(test_vk.ImageRenderData)});
|
|
||||||
std.debug.print("hello world {d}\n", .{@sizeOf(test_vk2.ImageRenderData)});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const test_vk = @import("test_vk");
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
const stdout_file = std.io.getStdOut().writer();
|
|
||||||
var bw = std.io.bufferedWriter(stdout_file);
|
|
||||||
const zout = bw.writer();
|
|
||||||
|
|
||||||
try zout.print("\n\nHello World!\n\nThis is a sample program using reflected type info from\n", .{});
|
|
||||||
try zout.print("the shader in `test_shaders/test_vk.vert`\n\n", .{});
|
|
||||||
try zout.print("sizeOf {s} == {d}\n", .{ @typeName(test_vk.ImageRenderData), @sizeOf(test_vk.ImageRenderData) });
|
|
||||||
try zout.print("The following fields, types and offsets are in {s}:\n", .{@typeName(test_vk.ImageRenderData)});
|
|
||||||
for (test_vk.ImageRenderData.FieldDetails) |field| {
|
|
||||||
try zout.print(" name={s}, offset={d}, size={d}\n", .{ field.name, field.offset, field.size });
|
|
||||||
}
|
|
||||||
try bw.flush();
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const mod = b.addModule("glslTypes", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.root_source_file = b.path("glslTypes.zig"),
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = mod;
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
.{
|
|
||||||
.name = "glslTypes",
|
|
||||||
.version = "0.0.0",
|
|
||||||
.dependencies = .{},
|
|
||||||
.paths = .{
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub const vec2 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const int = i32;
|
|
||||||
pub const uint = u32;
|
|
||||||
|
|
||||||
pub const u8vec4 = [4]u8;
|
|
||||||
|
|
||||||
pub const vec3 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
z: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
.z = o.z,
|
|
||||||
.pad = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const vec4 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
z: f32,
|
|
||||||
w: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
.z = o.z,
|
|
||||||
.w = o.w,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const mat4 = [4][4]f32;
|
|
||||||
|
|
||||||
pub const float = f32;
|
|
||||||
|
|
||||||
pub fn CheckFieldDetails(
|
|
||||||
comptime T: type,
|
|
||||||
comptime fieldName: []const u8,
|
|
||||||
expectedOffset: usize,
|
|
||||||
expectedSize: usize,
|
|
||||||
) void {
|
|
||||||
const offset = @offsetOf(T, fieldName);
|
|
||||||
const size = @sizeOf(@TypeOf(@field(std.mem.zeroes(T), fieldName)));
|
|
||||||
if (offset != expectedOffset) {
|
|
||||||
const msg = std.fmt.comptimePrint(
|
|
||||||
"Unexpected field offset, {s} was expected at offset {d} but found at offset {d}",
|
|
||||||
.{ fieldName, expectedOffset, offset },
|
|
||||||
);
|
|
||||||
@compileError(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != expectedSize) {
|
|
||||||
const msg = std.fmt.comptimePrint(
|
|
||||||
"Unexpected field size, '{s}' was expected with size {d} but found at size {d}",
|
|
||||||
.{ fieldName, expectedSize, size },
|
|
||||||
);
|
|
||||||
@compileError(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ValidateGeneratedStruct(comptime T: type) void {
|
|
||||||
for (@field(T, "FieldDetails")) |detail| {
|
|
||||||
CheckFieldDetails(T, detail.name, detail.offset, detail.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const FieldDetail = struct {
|
|
||||||
name: []const u8,
|
|
||||||
size: usize,
|
|
||||||
offset: usize,
|
|
||||||
};
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const mod = b.addModule("glslTypes", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.root_source_file = b.path("glslTypes.zig"),
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = mod;
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
.{
|
|
||||||
.name = "glslTypes",
|
|
||||||
.version = "0.0.0",
|
|
||||||
.dependencies = .{},
|
|
||||||
.paths = .{
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub const vec2 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const int = i32;
|
|
||||||
pub const uint = u32;
|
|
||||||
|
|
||||||
pub const u8vec4 = [4]u8;
|
|
||||||
|
|
||||||
pub const vec3 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
z: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
.z = o.z,
|
|
||||||
.pad = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const vec4 = extern struct {
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
z: f32,
|
|
||||||
w: f32,
|
|
||||||
|
|
||||||
pub fn from(o: anytype) @This() {
|
|
||||||
return .{
|
|
||||||
.x = o.x,
|
|
||||||
.y = o.y,
|
|
||||||
.z = o.z,
|
|
||||||
.w = o.w,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const mat4 = [4][4]f32;
|
|
||||||
|
|
||||||
pub const float = f32;
|
|
||||||
|
|
||||||
pub fn CheckFieldDetails(
|
|
||||||
comptime T: type,
|
|
||||||
comptime fieldName: []const u8,
|
|
||||||
expectedOffset: usize,
|
|
||||||
expectedSize: usize,
|
|
||||||
) void {
|
|
||||||
const offset = @offsetOf(T, fieldName);
|
|
||||||
const size = @sizeOf(@TypeOf(@field(std.mem.zeroes(T), fieldName)));
|
|
||||||
if (offset != expectedOffset) {
|
|
||||||
const msg = std.fmt.comptimePrint(
|
|
||||||
"Unexpected field offset, {s} was expected at offset {d} but found at offset {d}",
|
|
||||||
.{ fieldName, expectedOffset, offset },
|
|
||||||
);
|
|
||||||
@compileError(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != expectedSize) {
|
|
||||||
const msg = std.fmt.comptimePrint(
|
|
||||||
"Unexpected field size, '{s}' was expected with size {d} but found at size {d}",
|
|
||||||
.{ fieldName, expectedSize, size },
|
|
||||||
);
|
|
||||||
@compileError(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ValidateGeneratedStruct(comptime T: type) void {
|
|
||||||
for (@field(T, "FieldDetails")) |detail| {
|
|
||||||
CheckFieldDetails(T, detail.name, detail.offset, detail.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const FieldDetail = struct {
|
|
||||||
name: []const u8,
|
|
||||||
size: usize,
|
|
||||||
offset: usize,
|
|
||||||
};
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
#version 460
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 vPosition;
|
|
||||||
layout (location = 1) in vec3 vNormal;
|
|
||||||
layout (location = 2) in vec4 vColor;
|
|
||||||
layout (location = 3) in vec2 vTexCoord;
|
|
||||||
|
|
||||||
layout (location = 0) out vec4 outColor;
|
|
||||||
layout (location = 1) out vec2 texCoord;
|
|
||||||
|
|
||||||
struct ImageRenderData {
|
|
||||||
vec2 imagePosition;
|
|
||||||
vec2 imageSize;
|
|
||||||
vec2 anchorPoint;
|
|
||||||
vec2 scale;
|
|
||||||
float alpha;
|
|
||||||
vec4 baseColor;
|
|
||||||
float zLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ImageRenderData2{
|
|
||||||
ImageRenderData ird;
|
|
||||||
float someFloat;
|
|
||||||
vec2 someVec2;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) readonly buffer ImageBufferObjects {
|
|
||||||
ImageRenderData2 objects[];
|
|
||||||
} objectBuffer;
|
|
||||||
|
|
||||||
layout (push_constant) uniform constants
|
|
||||||
{
|
|
||||||
vec2 extent;
|
|
||||||
} PushConstants;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 imagePosition = objectBuffer.objects[gl_BaseInstance].ird.imagePosition;
|
|
||||||
vec2 imageSize = objectBuffer.objects[gl_BaseInstance].ird.imageSize;
|
|
||||||
vec2 anchor = objectBuffer.objects[gl_BaseInstance].ird.anchorPoint;
|
|
||||||
vec2 scale = objectBuffer.objects[gl_BaseInstance].ird.scale;
|
|
||||||
float alpha = objectBuffer.objects[gl_BaseInstance].ird.alpha;
|
|
||||||
vec4 baseColor = objectBuffer.objects[gl_BaseInstance].ird.baseColor;
|
|
||||||
|
|
||||||
vec2 finalSize = (imageSize / PushConstants.extent);
|
|
||||||
|
|
||||||
vec2 finalPos = ((imagePosition / PushConstants.extent) * 2 - 1) - anchor * finalSize * scale;
|
|
||||||
|
|
||||||
outColor = baseColor;
|
|
||||||
gl_Position = vec4(
|
|
||||||
finalPos.x + ( vPosition.x * finalSize.x ),
|
|
||||||
finalPos.y + (-vPosition.y * finalSize.y ),
|
|
||||||
vPosition.z, 1.0
|
|
||||||
);
|
|
||||||
|
|
||||||
texCoord = vec2(1 - vTexCoord.x, vTexCoord.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,288 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
arena: std.heap.ArenaAllocator,
|
|
||||||
allocator: std.mem.Allocator,
|
|
||||||
fileName: []const u8,
|
|
||||||
|
|
||||||
typeIdNames: std.StringArrayHashMap([]const u8),
|
|
||||||
reflectedTypes: std.StringArrayHashMap(ReflectedTypeInfo),
|
|
||||||
|
|
||||||
// some runtime options
|
|
||||||
opts: Options,
|
|
||||||
|
|
||||||
const Options = struct {
|
|
||||||
verbose: bool = false,
|
|
||||||
embedFile: ?[]const u8 = null,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ReflectedField = struct {
|
|
||||||
name: []u8,
|
|
||||||
typeName: []u8,
|
|
||||||
size: usize,
|
|
||||||
offset: usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ReflectedTypeInfo = struct {
|
|
||||||
name: []u8,
|
|
||||||
fields: std.ArrayList(ReflectedField),
|
|
||||||
size: usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn err(_: @This(), comptime fmt: []const u8, args: anytype) void {
|
|
||||||
std.debug.print("[ERROR ]:" ++ fmt ++ "\n", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn warn(_: @This(), comptime fmt: []const u8, args: anytype) void {
|
|
||||||
std.debug.print("[WARNING]:" ++ fmt ++ "\n", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn logv(self: @This(), comptime fmt: []const u8, args: anytype) void {
|
|
||||||
if (self.opts.verbose) {
|
|
||||||
std.debug.print("[VERBOSE]:" ++ fmt ++ "\n", args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reflect(allocator: std.mem.Allocator, fileName: []const u8, opts: Options) !@This() {
|
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
||||||
const arenaAlloc = arena.allocator();
|
|
||||||
var self = @This(){
|
|
||||||
.arena = arena,
|
|
||||||
.allocator = arenaAlloc,
|
|
||||||
.fileName = fileName,
|
|
||||||
.typeIdNames = std.StringArrayHashMap([]const u8).init(arenaAlloc),
|
|
||||||
.reflectedTypes = std.StringArrayHashMap(ReflectedTypeInfo).init(arenaAlloc),
|
|
||||||
.opts = opts,
|
|
||||||
};
|
|
||||||
|
|
||||||
var file = try std.fs.cwd().openFile(fileName, .{});
|
|
||||||
const fileContents = try file.readToEndAlloc(allocator, 10000000);
|
|
||||||
defer allocator.free(fileContents);
|
|
||||||
|
|
||||||
var tree = try std.json.parseFromSlice(std.json.Value, allocator, fileContents, .{});
|
|
||||||
defer tree.deinit();
|
|
||||||
//var tree = try parser.parseFromSlice(fileContents);
|
|
||||||
var root = tree.value.object;
|
|
||||||
//defer tree.deinit();
|
|
||||||
|
|
||||||
if (root.get("types")) |maybe| {
|
|
||||||
const typesRef = maybe.object;
|
|
||||||
for (typesRef.keys(), typesRef.values()) |k, v| {
|
|
||||||
const reflectedType = self.generateReflectedTypeInfo(v.object) catch |e| {
|
|
||||||
if (e == error.DummyObject) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try self.reflectedTypes.put(try dupeString(self.allocator, k), reflectedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
try self.updateReflectedSizes();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.get("ssbos")) |maybe| {
|
|
||||||
const ssbos = maybe.array;
|
|
||||||
for (ssbos.items) |ssboObject| {
|
|
||||||
self.logv("ssbo {s}", .{ssboObject.object.get("name").?.string});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dupeString(allocator: std.mem.Allocator, str: []const u8) ![]u8 {
|
|
||||||
return try std.fmt.allocPrint(allocator, "{s}", .{str});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn updateReflectedSize(self: *@This(), typeToUpdate: []const u8) void {
|
|
||||||
var reflected = self.reflectedTypes.getPtr(typeToUpdate).?;
|
|
||||||
|
|
||||||
if (reflected.size != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// get the last element
|
|
||||||
if (reflected.fields.items.len > 0) {
|
|
||||||
const lastField = reflected.fields.items[reflected.fields.items.len - 1];
|
|
||||||
if (lastField.typeName[0] == '_') {
|
|
||||||
self.updateReflectedSize(lastField.typeName);
|
|
||||||
reflected.size = lastField.offset + self.reflectedTypes.get(lastField.typeName).?.size;
|
|
||||||
} else {
|
|
||||||
// TODO: apply some padding rules
|
|
||||||
reflected.size = lastField.offset + lastField.size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn updateReflectedSizes(self: *@This()) !void {
|
|
||||||
for (self.reflectedTypes.keys()) |key| {
|
|
||||||
self.updateReflectedSize(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (self.reflectedTypes.values()) |*v| {
|
|
||||||
for (v.fields.items) |*field| {
|
|
||||||
if (field.typeName[0] == '_') {
|
|
||||||
field.size = self.reflectedTypes.get(field.typeName).?.size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn generateReflectedTypeInfo(self: @This(), typeObject: std.json.ObjectMap) !ReflectedTypeInfo {
|
|
||||||
var info = ReflectedTypeInfo{
|
|
||||||
.fields = std.ArrayList(ReflectedField).init(self.allocator),
|
|
||||||
.name = try dupeString(self.allocator, typeObject.get("name").?.string),
|
|
||||||
.size = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (typeObject.get("members").?.array.items) |member| {
|
|
||||||
var reflectedField = ReflectedField{
|
|
||||||
.name = try dupeString(self.allocator, member.object.get("name").?.string),
|
|
||||||
.typeName = try dupeString(self.allocator, member.object.get("type").?.string),
|
|
||||||
.size = 0,
|
|
||||||
.offset = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (member.object.get("offset")) |offset| {
|
|
||||||
reflectedField.offset = @as(usize, @intCast(offset.integer));
|
|
||||||
} else {
|
|
||||||
return error.DummyObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine size
|
|
||||||
//
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "int"))
|
|
||||||
reflectedField.size = 4;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "uint"))
|
|
||||||
reflectedField.size = 4;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "vec2"))
|
|
||||||
reflectedField.size = 8;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "vec4"))
|
|
||||||
reflectedField.size = 16;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "float"))
|
|
||||||
reflectedField.size = 4;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "mat4"))
|
|
||||||
reflectedField.size = 64;
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "vec3")) {
|
|
||||||
self.warn("vec3 usage detected, this is poorly supported by many vendors", .{});
|
|
||||||
reflectedField.size = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std.mem.eql(u8, reflectedField.typeName, "u8vec4")) {
|
|
||||||
reflectedField.size = 4;
|
|
||||||
}
|
|
||||||
try info.fields.append(reflectedField);
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
|
||||||
self.arena.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render(self: *@This(), allocator: std.mem.Allocator) ![]u8 {
|
|
||||||
var ostring = std.ArrayList(u8).init(allocator);
|
|
||||||
defer ostring.deinit();
|
|
||||||
var writer = ostring.writer();
|
|
||||||
|
|
||||||
var validateChunk = std.ArrayList(u8).init(allocator);
|
|
||||||
defer validateChunk.deinit();
|
|
||||||
var validate = validateChunk.writer();
|
|
||||||
try validate.writeAll("comptime {");
|
|
||||||
|
|
||||||
// write the preamble
|
|
||||||
try writer.writeAll("// This file is automatically generated\n");
|
|
||||||
try writer.writeAll("const gl = @import(\"glslTypes\");\n\n");
|
|
||||||
if (self.opts.embedFile) |embedFile| {
|
|
||||||
// std.debug.print("embedFile = {s}\n", .{embedFile});
|
|
||||||
try writer.print("pub const spirv_raw = @embedFile(\"{s}\");\n", .{embedFile});
|
|
||||||
try writer.print("pub const spirv: *const[spirv_raw.len: 0] u8 align(4) = spirv_raw;\n", .{});
|
|
||||||
try writer.print("pub fn spv() []const u32 {{ var p: []const u32 = undefined; p.ptr = @alignCast(@ptrCast(spirv.ptr)); p.len = spirv.len / 4; return p; }}", .{});
|
|
||||||
// try writer.print("pub fn spv() []const u32 {{ " ++
|
|
||||||
// "var p: []const u32; " ++
|
|
||||||
// "p.ptr = @ptrCast(spirv.ptr);" ++
|
|
||||||
// "p.len = spirv.len >> 2; return p; }} ", .{});
|
|
||||||
// std.debug.print("{s}", .{ostring.items});
|
|
||||||
}
|
|
||||||
try writer.writeAll("const vec2 = gl.vec2;\n");
|
|
||||||
try writer.writeAll("const vec3 = gl.vec3;\n");
|
|
||||||
try writer.writeAll("const vec4 = gl.vec4;\n");
|
|
||||||
try writer.writeAll("const mat4 = gl.mat4;\n");
|
|
||||||
try writer.writeAll("const float = gl.float;\n");
|
|
||||||
try writer.writeAll("const u8vec4 = gl.u8vec4;\n");
|
|
||||||
try writer.writeAll("const uint = gl.uint;\n");
|
|
||||||
try writer.writeAll("const int = gl.int;\n");
|
|
||||||
|
|
||||||
for (self.reflectedTypes.values()) |reflected| {
|
|
||||||
if (std.mem.eql(u8, reflected.name, "gl_PerVertex")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var testChunk = std.ArrayList(u8).init(allocator);
|
|
||||||
defer testChunk.deinit();
|
|
||||||
var testChunkWriter = testChunk.writer();
|
|
||||||
|
|
||||||
try validate.print("gl.ValidateGeneratedStruct({s});", .{reflected.name});
|
|
||||||
|
|
||||||
try testChunkWriter.writeAll("\npub const FieldDetails: []const gl.FieldDetail = &.{\n");
|
|
||||||
|
|
||||||
try writer.print("\npub const {s} = extern struct {{ \n", .{reflected.name});
|
|
||||||
var currentOffset: usize = 0;
|
|
||||||
var padCount: usize = 0;
|
|
||||||
for (reflected.fields.items) |field| {
|
|
||||||
const expected: usize = field.offset;
|
|
||||||
|
|
||||||
try testChunkWriter.print(".{{ .name = \"{s}\", .offset = {d}, .size = {d} }},\n", .{ field.name, expected, field.size });
|
|
||||||
|
|
||||||
if (currentOffset != expected) {
|
|
||||||
if (currentOffset > expected) {
|
|
||||||
self.err(
|
|
||||||
"`{s}` has field `{s}` with invalid offsets. Expected to be at `{d}` but current offset is already `{d}`",
|
|
||||||
.{
|
|
||||||
reflected.name,
|
|
||||||
field.name,
|
|
||||||
expected,
|
|
||||||
currentOffset,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try writer.print("pad{d}:[{d}]u8,\n", .{ padCount, expected - currentOffset });
|
|
||||||
currentOffset += expected - currentOffset;
|
|
||||||
padCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.typeName[0] != '_') {
|
|
||||||
try writer.print("{s}: {s}, \n", .{ field.name, field.typeName });
|
|
||||||
} else {
|
|
||||||
const refTypeName = self.reflectedTypes.get(field.typeName).?.name;
|
|
||||||
try writer.print("{s}: {s}, \n", .{ field.name, refTypeName });
|
|
||||||
}
|
|
||||||
currentOffset += field.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
try testChunkWriter.writeAll("};\n");
|
|
||||||
|
|
||||||
try writer.writeAll(testChunk.items);
|
|
||||||
try writer.writeAll("};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
try validate.writeAll("}");
|
|
||||||
try writer.writeAll(validateChunk.items);
|
|
||||||
|
|
||||||
try ostring.append(0);
|
|
||||||
var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(ostring.items[0 .. ostring.items.len - 1])), .zig);
|
|
||||||
std.debug.print("output={s}", .{ostring.items[0 .. ostring.items.len - 1]});
|
|
||||||
defer ast.deinit(allocator);
|
|
||||||
const out = try ast.render(allocator);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
// Copyright (c) peterino2@github.com
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const ReflectedJsonInfo = @import("ReflectedJsonInfo.zig");
|
|
||||||
|
|
||||||
const ProgramOptions = struct {
|
|
||||||
outputFile: []u8,
|
|
||||||
verbose: bool = false,
|
|
||||||
sourceFile: ?[]u8 = null,
|
|
||||||
errorMsg: ?[]u8 = null,
|
|
||||||
embedFile: ?[]u8 = null,
|
|
||||||
|
|
||||||
pub fn deinit(self: @This(), allocator: std.mem.Allocator) void {
|
|
||||||
allocator.free(self.outputFile);
|
|
||||||
if (self.sourceFile) |src| {
|
|
||||||
allocator.free(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.errorMsg) |msg| {
|
|
||||||
allocator.free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.embedFile) |embedFile| {
|
|
||||||
allocator.free(embedFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fn matchArgOpt(arg: []const u8, long: []const u8, short: ?[]const u8) bool {
|
|
||||||
if (arg.len < 2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg[0] == '-') {
|
|
||||||
if (arg[1] == '-') {
|
|
||||||
return std.mem.eql(u8, arg[2..], long);
|
|
||||||
} else if (short) |s| {
|
|
||||||
return arg[1] == s[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dupe(allocator: std.mem.Allocator, str: []const u8) ![]u8 {
|
|
||||||
return try std.fmt.allocPrint(allocator, "{s}", .{str});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseArgs(allocator: std.mem.Allocator) !ProgramOptions {
|
|
||||||
const ParseState = enum {
|
|
||||||
zero,
|
|
||||||
default,
|
|
||||||
output,
|
|
||||||
embed,
|
|
||||||
};
|
|
||||||
|
|
||||||
var state: ParseState = .zero;
|
|
||||||
|
|
||||||
var opts: ProgramOptions = .{
|
|
||||||
.outputFile = try dupe(allocator, "reflected_spirv.zig"),
|
|
||||||
};
|
|
||||||
const args = try std.process.argsAlloc(allocator);
|
|
||||||
defer std.process.argsFree(allocator, args);
|
|
||||||
|
|
||||||
for (args) |arg| {
|
|
||||||
switch (state) {
|
|
||||||
.zero => {
|
|
||||||
state = .default;
|
|
||||||
},
|
|
||||||
.default => {
|
|
||||||
if (arg[0] == '-') {
|
|
||||||
if (matchArgOpt(arg, "embed", "e"))
|
|
||||||
state = .embed;
|
|
||||||
if (matchArgOpt(arg, "output", "o"))
|
|
||||||
state = .output;
|
|
||||||
if (matchArgOpt(arg, "verbose", "v"))
|
|
||||||
opts.verbose = true;
|
|
||||||
} else {
|
|
||||||
if (opts.sourceFile) |src| {
|
|
||||||
allocator.free(src);
|
|
||||||
opts.sourceFile = null;
|
|
||||||
opts.errorMsg = try dupe(allocator, "Too many source files, this is not supported");
|
|
||||||
return opts;
|
|
||||||
}
|
|
||||||
opts.sourceFile = try dupe(allocator, arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.output => {
|
|
||||||
allocator.free(opts.outputFile);
|
|
||||||
opts.outputFile = try dupe(allocator, arg);
|
|
||||||
state = .default;
|
|
||||||
},
|
|
||||||
.embed => {
|
|
||||||
const embedFile = try dupe(allocator, arg);
|
|
||||||
|
|
||||||
const replacements = std.mem.replace(u8, arg, "\\", "/", embedFile);
|
|
||||||
_ = replacements;
|
|
||||||
|
|
||||||
if (opts.embedFile != null)
|
|
||||||
allocator.free(opts.embedFile.?);
|
|
||||||
|
|
||||||
opts.embedFile = embedFile;
|
|
||||||
state = .default;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return opts;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn usage() void {
|
|
||||||
std.debug.print("usage: spirv-reflect <input file> [-o or --output] <output file>\n", .{});
|
|
||||||
std.debug.print("the input file is the json file which is the result from running spirv-cross --reflect\n", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
||||||
const allocator = gpa.allocator();
|
|
||||||
defer _ = gpa.deinit();
|
|
||||||
|
|
||||||
const opts = try parseArgs(allocator);
|
|
||||||
defer opts.deinit(allocator);
|
|
||||||
if (opts.errorMsg) |msg| {
|
|
||||||
std.debug.print("{s}\n", .{msg});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.sourceFile == null) {
|
|
||||||
std.debug.print("Missing Source file. \n", .{});
|
|
||||||
usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.verbose)
|
|
||||||
std.debug.print("parsing: {s} >> {s}\n", .{ opts.sourceFile.?, opts.outputFile });
|
|
||||||
|
|
||||||
var reflectedJson = try ReflectedJsonInfo.reflect(
|
|
||||||
allocator,
|
|
||||||
opts.sourceFile.?,
|
|
||||||
.{
|
|
||||||
.verbose = opts.verbose,
|
|
||||||
.embedFile = opts.embedFile,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
defer reflectedJson.deinit();
|
|
||||||
|
|
||||||
const rendered = try reflectedJson.render(allocator);
|
|
||||||
defer allocator.free(rendered);
|
|
||||||
try std.fs.cwd().writeFile(.{
|
|
||||||
.sub_path = opts.outputFile,
|
|
||||||
.data = rendered,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
// todo, put some tests here
|
|
||||||
|
|
@ -6,24 +6,15 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const spng_c = if (static_build)
|
const spng_c = b.addLibrary(.{
|
||||||
b.addStaticLibrary(
|
.linkage = if (static_build) .static else .dynamic,
|
||||||
.{
|
.name = "spng_c",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.target = target,
|
.target = target,
|
||||||
.name = "spng_c",
|
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
},
|
}),
|
||||||
)
|
});
|
||||||
else
|
|
||||||
b.addSharedLibrary(
|
|
||||||
.{
|
|
||||||
.optimize = optimize,
|
|
||||||
.target = target,
|
|
||||||
.name = "spng_c",
|
|
||||||
.link_libc = true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
spng_c.addCSourceFile(.{ .file = b.path("spng/spng.c") });
|
spng_c.addCSourceFile(.{ .file = b.path("spng/spng.c") });
|
||||||
spng_c.addCSourceFile(.{ .file = b.path("miniz.c") });
|
spng_c.addCSourceFile(.{ .file = b.path("miniz.c") });
|
||||||
|
|
@ -46,10 +37,12 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
const test_step = b.step("test", "run unit tests for spng");
|
const test_step = b.step("test", "run unit tests for spng");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/spng.zig"),
|
.root_source_file = b.path("src/spng.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
tests.root_module.linkLibrary(spng_c);
|
tests.root_module.linkLibrary(spng_c);
|
||||||
tests.root_module.addIncludePath(b.path("spng"));
|
tests.root_module.addIncludePath(b.path("spng"));
|
||||||
|
|
|
||||||
|
|
@ -126,9 +126,7 @@ pub const SpngContext = struct {
|
||||||
pub fn loadFileAlloc(filename: []const u8, allocator: std.mem.Allocator) ![]u8 {
|
pub fn loadFileAlloc(filename: []const u8, allocator: std.mem.Allocator) ![]u8 {
|
||||||
var file = try std.fs.cwd().openFile(filename, .{});
|
var file = try std.fs.cwd().openFile(filename, .{});
|
||||||
const filesize = (try file.stat()).size;
|
const filesize = (try file.stat()).size;
|
||||||
const buffer: []u8 = try allocator.alignedAlloc(u8, 8, filesize);
|
return file.readToEndAlloc(allocator, filesize);
|
||||||
try file.reader().readNoEof(buffer);
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "spngtest" {
|
test "spngtest" {
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,12 @@ pub fn build(b: *std.Build) void {
|
||||||
const test_step = b.step("test", "run unit tests for sdl3");
|
const test_step = b.step("test", "run unit tests for sdl3");
|
||||||
const tests = b.addExecutable(.{
|
const tests = b.addExecutable(.{
|
||||||
.name = "test",
|
.name = "test",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
|
.root_source_file = b.path("sdl3test/sdl3test.zig"),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.addCSourceFile(.{
|
tests.addCSourceFile(.{
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ static const GLchar *GLFrag =
|
||||||
"const vec3 Rcoeff = vec3(1.164, 0.000, 1.793);\n"
|
"const vec3 Rcoeff = vec3(1.164, 0.000, 1.793);\n"
|
||||||
"const vec3 Gcoeff = vec3(1.164, -0.213, -0.533);\n"
|
"const vec3 Gcoeff = vec3(1.164, -0.213, -0.533);\n"
|
||||||
"const vec3 Bcoeff = vec3(1.164, 2.112, 0.000);\n"
|
"const vec3 Bcoeff = vec3(1.164, 2.112, 0.000);\n"
|
||||||
|
|
||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
" vec2 tcoord;\n"
|
" vec2 tcoord;\n"
|
||||||
" vec3 yuv, rgb;\n"
|
" vec3 yuv, rgb;\n"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
pub fn main() !void {}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
pub fn main() !void {}
|
||||||
|
|
@ -54,9 +54,11 @@ pub fn build(b: *std.Build) void {
|
||||||
// ========== tests =============
|
// ========== tests =============
|
||||||
const test_step = b.step("test", "run unit tests for tracy");
|
const test_step = b.step("test", "run unit tests for tracy");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("tracy_test.zig"),
|
.root_source_file = b.path("tracy_test.zig"),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
tests.root_module.addImport("tracy", mod);
|
tests.root_module.addImport("tracy", mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub const enabled = @import("build_options").tracy_enabled;
|
||||||
|
|
||||||
const debug_verify_stack_order = true;
|
const debug_verify_stack_order = true;
|
||||||
|
|
||||||
pub usingnamespace if (enabled) tracy_full else tracy_stub;
|
pub const t = if (enabled) tracy_full else tracy_stub;
|
||||||
|
|
||||||
const tracy_stub = struct {
|
const tracy_stub = struct {
|
||||||
pub const ZoneCtx = struct {
|
pub const ZoneCtx = struct {
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,7 @@ const tracy = @import("tracy");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
test "test-tracy-integration" {
|
test "test-tracy-integration" {
|
||||||
|
const z = tracy.t.ZoneNC(@src(), "hello", 0xaaaaaa);
|
||||||
std.debug.print("tracy integration testing enabled = {any}", .{tracy.enabled});
|
std.debug.print("tracy integration testing enabled = {any}", .{tracy.enabled});
|
||||||
|
z.End();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue