Low cortisol depth management
This commit is contained in:
parent
655dca998b
commit
7e1d95054e
20 changed files with 2131 additions and 58 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
.zig-cache/
|
||||
zig-pkg/
|
||||
zig-out/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ src/rhi/vulkan/resource.zig
|
|||
| `makeX(...)` | Creates an RHI resource and returns its handle |
|
||||
| `deleteX(handle)` | Releases the resource and removes it from the resource pool |
|
||||
| `releaseX(handle)` | Releases the resource without removing it from the resource pool |
|
||||
| `getXInfo(handle)` | Returns backend-independent information about the resource |
|
||||
| `getRawVkX(handle)` | Returns the backend-specific raw Vulkan GPU handle |
|
||||
|
||||
## Example
|
||||
|
|
|
|||
19
build.zig
19
build.zig
|
|
@ -58,6 +58,14 @@ pub fn build(b: *std.Build) !void {
|
|||
mod.addImport("stb_image", stb_image.createModule());
|
||||
mod.addCSourceFile(.{ .file = b.path("src/vendor/stb_image/stb_image.c") });
|
||||
|
||||
const fast_obj = b.addTranslateC(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("./src/vendor/fast_obj/fast_obj.h"),
|
||||
});
|
||||
mod.addImport("fast_obj", fast_obj.createModule());
|
||||
mod.addCSourceFiles(.{ .files = &.{"src/vendor/fast_obj/fast_obj.c"} });
|
||||
|
||||
//
|
||||
// EXAMPLES
|
||||
//
|
||||
|
|
@ -67,6 +75,7 @@ pub fn build(b: *std.Build) !void {
|
|||
src: []const u8,
|
||||
}{
|
||||
.{ .name = "simple", .src = "examples/simple/simple.zig" },
|
||||
.{ .name = "3D", .src = "examples/simple_3D/simple_3D.zig" },
|
||||
}) |excfg| {
|
||||
const ex_name = excfg.name;
|
||||
const ex_src = excfg.src;
|
||||
|
|
@ -110,13 +119,19 @@ pub fn build(b: *std.Build) !void {
|
|||
example.root_module.addImport("sdl", sdl.createModule());
|
||||
example.root_module.linkSystemLibrary("SDL3", .{});
|
||||
|
||||
const example_math = b.dependency("NYXMath", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
example.root_module.addImport("math", example_math.module("NYXMath"));
|
||||
|
||||
const example_run = b.addRunArtifact(example);
|
||||
example_run_step.dependOn(&example_run.step);
|
||||
|
||||
const example_build_step = b.addInstallArtifact(example, .{});
|
||||
example_step.dependOn(&example_build_step.step);
|
||||
|
||||
const check_step = b.step("check", "Check if compiles");
|
||||
check_step.dependOn(&example.step);
|
||||
// const check_step = b.step("check", "Check if compiles");
|
||||
// check_step.dependOn(&example.step);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
clear
|
||||
|
||||
glslc examples/assets/shaders/simple.vert -o examples/assets/shaders/compiled/simple.vert.spv
|
||||
glslc examples/assets/shaders/simple.frag -o examples/assets/shaders/compiled/simple.frag.spv
|
||||
|
||||
glslc examples/assets/shaders/3D.vert -o examples/assets/shaders/compiled/3D.vert.spv
|
||||
glslc examples/assets/shaders/3D.frag -o examples/assets/shaders/compiled/3D.frag.spv
|
||||
|
|
|
|||
26
examples/assets/shaders/3D.frag
Normal file
26
examples/assets/shaders/3D.frag
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#version 450
|
||||
|
||||
//
|
||||
// IO
|
||||
//
|
||||
|
||||
layout(location = 0) in vec2 in_UV;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
//
|
||||
// UNIFORMS
|
||||
//
|
||||
|
||||
// layout(binding = 0) uniform UnlitMaterial {
|
||||
// vec4 albedo;
|
||||
// } material;
|
||||
|
||||
layout(binding = 2) uniform sampler2D albedo_texture;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
void main() {
|
||||
// out_color = vec4(1.0);
|
||||
out_color = texture(albedo_texture, in_UV);
|
||||
}
|
||||
45
examples/assets/shaders/3D.vert
Normal file
45
examples/assets/shaders/3D.vert
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#version 450
|
||||
|
||||
//
|
||||
// IN
|
||||
//
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 1) in vec3 in_normal;
|
||||
layout(location = 2) in vec2 in_UV;
|
||||
|
||||
//
|
||||
// OUT
|
||||
//
|
||||
|
||||
layout(location = 0) out vec2 out_UV;
|
||||
layout(location = 1) out vec3 out_normal;
|
||||
layout(location = 2) out vec3 out_world_position;
|
||||
|
||||
//
|
||||
// UNIFORMS
|
||||
//
|
||||
|
||||
layout(set = 0, binding = 0) uniform Camera {
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} camera;
|
||||
|
||||
layout(set = 0, binding = 1) uniform Model {
|
||||
mat4 model;
|
||||
} object;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
void main() {
|
||||
// --- GET WORLD POSITION ---
|
||||
vec4 world_position = object.model * vec4(in_position, 1.0);
|
||||
|
||||
// --- SHOW POSITION AT ---
|
||||
gl_Position = camera.projection * camera.view * world_position;
|
||||
|
||||
// --- SET ---
|
||||
out_UV = in_UV;
|
||||
out_normal = mat3(transpose(inverse(object.model))) * in_normal;
|
||||
out_world_position = world_position.xyz;
|
||||
}
|
||||
BIN
examples/assets/shaders/compiled/3D.frag.spv
Normal file
BIN
examples/assets/shaders/compiled/3D.frag.spv
Normal file
Binary file not shown.
BIN
examples/assets/shaders/compiled/3D.vert.spv
Normal file
BIN
examples/assets/shaders/compiled/3D.vert.spv
Normal file
Binary file not shown.
|
|
@ -77,15 +77,17 @@ pub fn main(init: std.process.Init) !void {
|
|||
}, init.gpa, init.io);
|
||||
defer gfx.deinit();
|
||||
|
||||
errdefer gfx.deinit();
|
||||
|
||||
// --- # ---
|
||||
const adapter = try gfx.makeAdapter(.{});
|
||||
const adapter = try gfx.makeAdapter(.{ .gpu_type = .any });
|
||||
const surface = try gfx.makeSurface();
|
||||
const device = try gfx.makeDevice(adapter, surface);
|
||||
const swapchain = try gfx.makeSwapchain(adapter, device, surface);
|
||||
|
||||
// --- TEXTURES ---
|
||||
const texture = try gfx.makeTexture(.{
|
||||
.image = .{ .path = "examples/assets/textures/texture.jpg" },
|
||||
.image = .{ .path = "examples/assets/textures/bully.jpg" },
|
||||
.sampler = .{ .min_filter = .linear, .address_u = .repeat },
|
||||
}, adapter, device);
|
||||
|
||||
|
|
@ -107,10 +109,12 @@ pub fn main(init: std.process.Init) !void {
|
|||
.vertex_binding = .{ .stride = @sizeOf(Vertex) },
|
||||
|
||||
.uniforms = &.{
|
||||
.{ .name = "material", .offset = 0, .size = @sizeOf(UnlitMaterial) },
|
||||
.{ .name = "material", .size = @sizeOf(UnlitMaterial) },
|
||||
},
|
||||
|
||||
.textures = &.{texture},
|
||||
.textures = &.{
|
||||
texture,
|
||||
},
|
||||
|
||||
.blend_mode = .alpha,
|
||||
|
||||
|
|
|
|||
253
examples/simple_3D/simple_3D.zig
Normal file
253
examples/simple_3D/simple_3D.zig
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
//! ----------------------------------------------------
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
const sdl = @import("sdl");
|
||||
const math = @import("math");
|
||||
const Gfx = @import("gfx");
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const UnlitMaterial = struct {
|
||||
albedo: [4]f32 = .{ 1, 1, 1, 1 },
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const Vertex = struct {
|
||||
pos: [3]f32,
|
||||
normal: [3]f32,
|
||||
uv: [2]f32,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const vertices = [_]Vertex{
|
||||
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 1 } },
|
||||
|
||||
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 1 } },
|
||||
|
||||
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 1 } },
|
||||
|
||||
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 1 } },
|
||||
|
||||
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 1 } },
|
||||
|
||||
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 0 } },
|
||||
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 0 } },
|
||||
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 1 } },
|
||||
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 1 } },
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const indices = [_]u32{
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
|
||||
4, 5, 6,
|
||||
4, 6, 7,
|
||||
|
||||
8, 9, 10,
|
||||
8, 10, 11,
|
||||
|
||||
12, 13, 14,
|
||||
12, 14, 15,
|
||||
|
||||
16, 17, 18,
|
||||
16, 18, 19,
|
||||
|
||||
20, 21, 22,
|
||||
20, 22, 23,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const Camera = struct {
|
||||
projection: math.Mat4x4,
|
||||
view: math.Mat4x4,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const Model = struct {
|
||||
matrix: math.Mat4x4,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
|
||||
//
|
||||
// DATA
|
||||
//
|
||||
|
||||
var material: UnlitMaterial = .{ .albedo = .{ 1.0, 0.2, 0.2, 1.0 } };
|
||||
const camera: Camera = .{
|
||||
.projection = .perspective(std.math.degreesToRadians(90), 800.0 / 600.0, 0.01, 1000),
|
||||
.view = .lookAt(.new(.{ 1, 1, -2 }), .new(.{ 0, 0, 1 }), .new(.{ 0, 1, 0 })),
|
||||
};
|
||||
const model: Model = .{
|
||||
.matrix = math.Mat4x4.translate(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
.mul(math.Quat.fromEuler(.init(0, 0, 0)).toMat4())
|
||||
.mul(math.Mat4x4.scale(
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
)),
|
||||
};
|
||||
|
||||
//
|
||||
// SDL
|
||||
//
|
||||
|
||||
// --- # ---
|
||||
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL;
|
||||
defer sdl.SDL_Quit();
|
||||
|
||||
// --- # ---
|
||||
const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow;
|
||||
defer sdl.SDL_DestroyWindow(window);
|
||||
|
||||
// --- # ---
|
||||
const props = sdl.SDL_GetWindowProperties(window);
|
||||
const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null);
|
||||
const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
|
||||
//
|
||||
// GFX
|
||||
//
|
||||
|
||||
// --- # ---
|
||||
var gfx: Gfx = try .init(.{
|
||||
.window = .{
|
||||
.xlib = .{
|
||||
.window = @intCast(xwindow),
|
||||
.display = display.?,
|
||||
},
|
||||
},
|
||||
.backend = .vulkan,
|
||||
}, init.gpa, init.io);
|
||||
defer gfx.deinit();
|
||||
|
||||
errdefer gfx.deinit();
|
||||
|
||||
// --- # ---
|
||||
const adapter = try gfx.makeAdapter(.{ .gpu_type = .any });
|
||||
const surface = try gfx.makeSurface();
|
||||
const device = try gfx.makeDevice(adapter, surface);
|
||||
const swapchain = try gfx.makeSwapchain(adapter, device, surface);
|
||||
|
||||
// --- TEXTURES ---
|
||||
const texture = try gfx.makeTexture(.{
|
||||
.image = .{ .path = "examples/assets/textures/texture.jpg", .vertical_flip = true },
|
||||
.sampler = .{ .min_filter = .linear, .address_u = .repeat },
|
||||
}, adapter, device);
|
||||
|
||||
// --- BUFFERS ---
|
||||
const vbuf = try gfx.makeBuffer(vertices, .vertex, adapter, device);
|
||||
const ibuf = try gfx.makeBuffer(indices, .index, adapter, device);
|
||||
|
||||
// --- SHADERS ---
|
||||
const simple_vert = try gfx.makeShader("examples/assets/shaders/compiled/3D.vert.spv", device);
|
||||
const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/3D.frag.spv", device);
|
||||
|
||||
// --- PIPELINE ---
|
||||
const pipeline = try gfx.makePipeline(.{
|
||||
.vertex_attributes = &.{
|
||||
.{ .location = 0, .format = .vec3, .offset = @offsetOf(Vertex, "pos") },
|
||||
.{ .location = 1, .format = .vec3, .offset = @offsetOf(Vertex, "normal") },
|
||||
.{ .location = 2, .format = .vec2, .offset = @offsetOf(Vertex, "uv") },
|
||||
},
|
||||
.vertex_binding = .{ .stride = @sizeOf(Vertex) },
|
||||
|
||||
.uniforms = &.{
|
||||
.{ .name = "camera", .size = @sizeOf(Camera) },
|
||||
.{ .name = "model", .size = @sizeOf(Model) },
|
||||
},
|
||||
|
||||
.textures = &.{
|
||||
texture,
|
||||
},
|
||||
|
||||
.depth_format = .d32_sfloat,
|
||||
|
||||
.vert_shader = simple_vert,
|
||||
.frag_shader = simple_frag,
|
||||
|
||||
.device = device,
|
||||
.swapchain = swapchain,
|
||||
});
|
||||
|
||||
// --- MISC ---
|
||||
var event: sdl.SDL_Event = undefined;
|
||||
var running: bool = true;
|
||||
var i: f32 = 0;
|
||||
|
||||
while (running) {
|
||||
// --- INPUTS ---
|
||||
while (sdl.SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
sdl.SDL_EVENT_QUIT => running = false,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
// --- ANIMATION ---
|
||||
i += 0.001;
|
||||
i = @mod(i, 1);
|
||||
material.albedo[1] = i;
|
||||
|
||||
try pipeline.setUniform("camera", Camera{
|
||||
.projection = camera.projection.transpose(),
|
||||
.view = camera.view.transpose(),
|
||||
});
|
||||
try pipeline.setUniform("model", Model{
|
||||
.matrix = model.matrix.transpose(),
|
||||
});
|
||||
|
||||
// --- FRAME ---
|
||||
try gfx.beginFrame(swapchain, device);
|
||||
defer gfx.endFrame(swapchain, device) catch unreachable;
|
||||
|
||||
// --- NEW PASS ---
|
||||
if (gfx.beginPass(swapchain, .{
|
||||
.clear_color = .{ 0.01, 0.01, 0.01, 1.0 },
|
||||
.depth_enabled = true,
|
||||
})) |pass| {
|
||||
defer pass.end();
|
||||
|
||||
try vbuf.bind();
|
||||
try ibuf.bind();
|
||||
|
||||
try pipeline.bind();
|
||||
pass.drawIndexed(indices.len, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
// --- NEW PASS ---
|
||||
if (gfx.beginPass(swapchain, .{
|
||||
.load_op = .load,
|
||||
})) |pass| {
|
||||
defer pass.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/gfx.zig
44
src/gfx.zig
|
|
@ -7,32 +7,34 @@ const std = @import("std");
|
|||
const gtl = @import("gtl");
|
||||
const vk = @import("vulkan");
|
||||
const common = @import("rhi/common.zig");
|
||||
const Handle = gtl.Handle;
|
||||
const Self = @This();
|
||||
|
||||
// --- # ---
|
||||
pub const Handle = gtl.Handle;
|
||||
|
||||
// --- CONFIGS ---
|
||||
const AdapterConfig = common.AdapterConfig;
|
||||
const RenderPassConfig = common.RenderPassConfig;
|
||||
const PipelineConfig = common.PipelineConfig;
|
||||
const BufferUsage = common.BufferUsage;
|
||||
const Pass = common.Pass;
|
||||
const ImageConfig = common.ImageConfig;
|
||||
const SamplerConfig = common.SamplerConfig;
|
||||
const TextureConfig = common.TextureConfig;
|
||||
pub const AdapterConfig = common.AdapterConfig;
|
||||
pub const RenderPassConfig = common.RenderPassConfig;
|
||||
pub const PipelineConfig = common.PipelineConfig;
|
||||
pub const BufferUsage = common.BufferUsage;
|
||||
pub const Pass = common.Pass;
|
||||
pub const ImageConfig = common.ImageConfig;
|
||||
pub const SamplerConfig = common.SamplerConfig;
|
||||
pub const TextureConfig = common.TextureConfig;
|
||||
|
||||
// --- HANDLES ---
|
||||
const Window = common.Window;
|
||||
const Adapter = common.Adapter;
|
||||
const Device = common.Device;
|
||||
const Buffer = common.Buffer;
|
||||
const Surface = common.Surface;
|
||||
const Swapchain = common.Swapchain;
|
||||
const Image = common.Image;
|
||||
const Sampler = common.Sampler;
|
||||
const Texture = common.Texture;
|
||||
pub const Window = common.Window;
|
||||
pub const Adapter = common.Adapter;
|
||||
pub const Device = common.Device;
|
||||
pub const Buffer = common.Buffer;
|
||||
pub const Surface = common.Surface;
|
||||
pub const Swapchain = common.Swapchain;
|
||||
pub const Image = common.Image;
|
||||
pub const Sampler = common.Sampler;
|
||||
pub const Texture = common.Texture;
|
||||
|
||||
const Shader = common.Shader;
|
||||
const Pipeline = common.Pipeline;
|
||||
pub const Shader = common.Shader;
|
||||
pub const Pipeline = common.Pipeline;
|
||||
|
||||
// --- RHI ---
|
||||
const VulkanRHI = @import("rhi/vulkan/vulkan.zig");
|
||||
|
|
@ -288,7 +290,7 @@ pub fn beginPass(
|
|||
config: RenderPassConfig,
|
||||
) ?Pass {
|
||||
switch (self.ctx) {
|
||||
.vulkan => |*v| v.beginRendering(swapchain, config) catch return null,
|
||||
.vulkan => |*v| v.beginPass(swapchain, config) catch return null,
|
||||
}
|
||||
|
||||
return .{
|
||||
|
|
|
|||
|
|
@ -93,10 +93,30 @@ pub const VertexAttribute = struct {
|
|||
/// ----------------------------------------------------
|
||||
pub const UniformDesc = struct {
|
||||
name: []const u8,
|
||||
offset: u32,
|
||||
size: u32,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const CompareOp = enum {
|
||||
never,
|
||||
less,
|
||||
equal,
|
||||
less_equal,
|
||||
greater,
|
||||
not_equal,
|
||||
greater_equal,
|
||||
always,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const DepthFormat = enum {
|
||||
d16_unorm,
|
||||
d24_unorm_s8,
|
||||
d32_sfloat,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub const PipelineConfig = struct {
|
||||
|
|
@ -127,12 +147,17 @@ pub const PipelineConfig = struct {
|
|||
front_face: enum {
|
||||
ccw,
|
||||
cw,
|
||||
} = .cw,
|
||||
} = .ccw,
|
||||
|
||||
blend_mode: enum {
|
||||
none,
|
||||
alpha,
|
||||
} = .none,
|
||||
|
||||
depth_format: ?DepthFormat = null,
|
||||
depth_test: bool = true,
|
||||
depth_write: bool = true,
|
||||
depth_compare: CompareOp = .less,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -145,7 +170,7 @@ pub const Pass = struct {
|
|||
/// ----------------------------------------------------
|
||||
pub fn end(self: *const Pass) void {
|
||||
switch (self.gfx.ctx) {
|
||||
.vulkan => |*v| v.endRendering(self.swapchain),
|
||||
.vulkan => |*v| v.endPass(self.swapchain),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,8 +210,18 @@ pub const StoreOp = enum {
|
|||
/// ----------------------------------------------------
|
||||
pub const RenderPassConfig = struct {
|
||||
clear_color: [4]f32 = .{ 0.0, 0.0, 0.0, 1.0 },
|
||||
|
||||
depth_enabled: bool = false,
|
||||
depth_format: DepthFormat = .d32_sfloat,
|
||||
depth_load_op: LoadOp = .clear,
|
||||
depth_store_op: StoreOp = .dont_care,
|
||||
|
||||
clear_depth: f32 = 1.0,
|
||||
clear_stencil: u8 = 0,
|
||||
|
||||
load_op: LoadOp = .clear,
|
||||
store_op: StoreOp = .store,
|
||||
|
||||
width: ?u32 = null,
|
||||
height: ?u32 = null,
|
||||
};
|
||||
|
|
@ -244,6 +279,7 @@ pub const AddressMode = enum {
|
|||
pub const ImageUsage = enum {
|
||||
texture,
|
||||
render_target,
|
||||
depth,
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -258,6 +294,8 @@ pub const ImageConfig = struct {
|
|||
/// Required for `.data`. `null` = use source dimensions
|
||||
size: ?[2]u32 = null,
|
||||
|
||||
vertical_flip: bool = false,
|
||||
|
||||
format: PixelFormat = .rgba8_srgb,
|
||||
usage: ImageUsage = .texture,
|
||||
mip_levels: u32 = 1,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ pub fn init(
|
|||
|
||||
if (config.path) |path| {
|
||||
var tex_channel: i32 = 0;
|
||||
stb.stbi_set_flip_vertically_on_load(@intFromBool(config.vertical_flip));
|
||||
const data = stb.stbi_load(path.ptr, &tex_size[0], &tex_size[1], &tex_channel, stb.STBI_rgb_alpha) orelse {
|
||||
return error.FileNotFound;
|
||||
};
|
||||
|
|
@ -86,6 +87,7 @@ pub fn init(
|
|||
switch (config.usage) {
|
||||
.texture => {},
|
||||
.render_target => usage |= vk.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.depth => usage |= vk.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
}
|
||||
|
||||
const image_info: vk.VkImageCreateInfo = .{
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ descriptor_sets: [MAX_FRAMES_IN_FLIGHT]vk.VkDescriptorSet = .{null} ** MAX_FRAME
|
|||
uniform_buffers: [MAX_FRAMES_IN_FLIGHT]vk.VkBuffer = .{null} ** MAX_FRAMES_IN_FLIGHT,
|
||||
uniform_memories: [MAX_FRAMES_IN_FLIGHT]vk.VkDeviceMemory = .{null} ** MAX_FRAMES_IN_FLIGHT,
|
||||
uniforms: []UniformDesc,
|
||||
uniform_offsets: []u32,
|
||||
|
||||
vulkan: *VulkanRHI,
|
||||
|
||||
|
|
@ -51,20 +52,37 @@ pub fn init(
|
|||
var self: Self = .{
|
||||
.device = device,
|
||||
.uniforms = &.{},
|
||||
.uniform_offsets = &.{},
|
||||
.vulkan = vulkan,
|
||||
.alloc = alloc,
|
||||
};
|
||||
errdefer self.deinit();
|
||||
|
||||
// --- COMPUTE UNIFORM LAYOUT ---
|
||||
// Each uniform block gets its own descriptor binding. Blocks are packed
|
||||
// into a single per-frame buffer, each at a `minUniformBufferOffsetAlignment`
|
||||
// aligned offset so the same layout maps to `glBindBufferRange` (GL) and
|
||||
// CBV offsets (D3D12) unchanged.
|
||||
var uniform_size: u32 = 0;
|
||||
for (config.uniforms) |u| {
|
||||
uniform_size = @max(uniform_size, u.offset + u.size);
|
||||
if (config.uniforms.len > 0) {
|
||||
var props: vk.VkPhysicalDeviceProperties = .{};
|
||||
vk.vkGetPhysicalDeviceProperties(device.physical_device, &props);
|
||||
|
||||
const alignment: u32 = @intCast(@max(
|
||||
@as(u64, 16),
|
||||
props.limits.minUniformBufferOffsetAlignment,
|
||||
));
|
||||
|
||||
const uniform_offsets = try alloc.alloc(u32, config.uniforms.len);
|
||||
self.uniform_offsets = uniform_offsets;
|
||||
|
||||
for (config.uniforms, 0..) |u, i| {
|
||||
uniform_offsets[i] = std.mem.alignForward(u32, uniform_size, alignment);
|
||||
uniform_size = uniform_offsets[i] + u.size;
|
||||
}
|
||||
uniform_size = std.mem.alignForward(u32, uniform_size, 16);
|
||||
uniform_size = std.mem.alignForward(u32, uniform_size, alignment);
|
||||
|
||||
// --- COPY UNIFORMS ---
|
||||
if (config.uniforms.len > 0) {
|
||||
const uniforms = try alloc.alloc(UniformDesc, config.uniforms.len);
|
||||
@memcpy(uniforms, config.uniforms);
|
||||
self.uniforms = uniforms;
|
||||
|
|
@ -83,9 +101,9 @@ pub fn init(
|
|||
var bindings: [MAX_BINDINGS]vk.VkDescriptorSetLayoutBinding = undefined;
|
||||
var binding_count: u32 = 0;
|
||||
|
||||
if (uniform_size > 0) {
|
||||
for (config.uniforms, 0..) |_, i| {
|
||||
bindings[binding_count] = .{
|
||||
.binding = 0,
|
||||
.binding = @intCast(i),
|
||||
.descriptorType = vk.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = vk.VK_SHADER_STAGE_VERTEX_BIT | vk.VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
|
|
@ -94,9 +112,9 @@ pub fn init(
|
|||
binding_count += 1;
|
||||
}
|
||||
|
||||
for (0..texture_count) |i| {
|
||||
for (config.textures, 0..) |_, i| {
|
||||
bindings[binding_count] = .{
|
||||
.binding = @intCast(i + 1),
|
||||
.binding = @intCast(config.uniforms.len + i),
|
||||
.descriptorType = vk.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = vk.VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
|
|
@ -298,10 +316,29 @@ pub fn init(
|
|||
.pAttachments = &color_blend_attachment,
|
||||
};
|
||||
|
||||
var depth_stencil: vk.VkPipelineDepthStencilStateCreateInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
.depthTestEnable = if (config.depth_test) vk.VK_TRUE else vk.VK_FALSE,
|
||||
.depthWriteEnable = if (config.depth_write) vk.VK_TRUE else vk.VK_FALSE,
|
||||
.depthCompareOp = switch (config.depth_compare) {
|
||||
.never => vk.VK_COMPARE_OP_NEVER,
|
||||
.less => vk.VK_COMPARE_OP_LESS,
|
||||
.equal => vk.VK_COMPARE_OP_EQUAL,
|
||||
.less_equal => vk.VK_COMPARE_OP_LESS_OR_EQUAL,
|
||||
.greater => vk.VK_COMPARE_OP_GREATER,
|
||||
.not_equal => vk.VK_COMPARE_OP_NOT_EQUAL,
|
||||
.greater_equal => vk.VK_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
.always => vk.VK_COMPARE_OP_ALWAYS,
|
||||
},
|
||||
.depthBoundsTestEnable = vk.VK_FALSE,
|
||||
.stencilTestEnable = vk.VK_FALSE,
|
||||
};
|
||||
|
||||
var rendering_info: vk.VkPipelineRenderingCreateInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachmentFormats = &swapchain.format,
|
||||
.depthAttachmentFormat = if (config.depth_format) |f| VulkanRHI.depthFormatToVk(f) else vk.VK_FORMAT_UNDEFINED,
|
||||
};
|
||||
|
||||
var pipeline_info: vk.VkGraphicsPipelineCreateInfo = .{
|
||||
|
|
@ -316,6 +353,7 @@ pub fn init(
|
|||
.pRasterizationState = &rasterizer,
|
||||
.pMultisampleState = &multisampling,
|
||||
.pColorBlendState = &color_blending,
|
||||
.pDepthStencilState = if (config.depth_format != null) &depth_stencil else null,
|
||||
.pDynamicState = &dynamic_state,
|
||||
|
||||
.layout = pipeline_layout,
|
||||
|
|
@ -347,10 +385,10 @@ pub fn init(
|
|||
var pool_sizes: [2]vk.VkDescriptorPoolSize = undefined;
|
||||
var pool_size_count: u32 = 0;
|
||||
|
||||
if (uniform_size > 0) {
|
||||
if (config.uniforms.len > 0) {
|
||||
pool_sizes[pool_size_count] = .{
|
||||
.type = vk.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = @intCast(MAX_FRAMES_IN_FLIGHT),
|
||||
.descriptorCount = @intCast(MAX_FRAMES_IN_FLIGHT * config.uniforms.len),
|
||||
};
|
||||
pool_size_count += 1;
|
||||
}
|
||||
|
|
@ -440,24 +478,24 @@ pub fn init(
|
|||
// --- WRITE DESCRIPTOR SET ---
|
||||
var writes: [MAX_WRITES]vk.VkWriteDescriptorSet = undefined;
|
||||
var write_count: u32 = 0;
|
||||
var buffer_descriptor: vk.VkDescriptorBufferInfo = undefined;
|
||||
var buffer_descriptors: [MAX_BINDINGS]vk.VkDescriptorBufferInfo = undefined;
|
||||
var image_descriptors: [MAX_TEXTURES]vk.VkDescriptorImageInfo = undefined;
|
||||
|
||||
if (uniform_size > 0) {
|
||||
buffer_descriptor = .{
|
||||
for (config.uniforms, 0..) |u, i| {
|
||||
buffer_descriptors[i] = .{
|
||||
.buffer = self.uniform_buffers[frame],
|
||||
.offset = 0,
|
||||
.range = uniform_size,
|
||||
.offset = self.uniform_offsets[i],
|
||||
.range = u.size,
|
||||
};
|
||||
|
||||
writes[write_count] = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self.descriptor_sets[frame],
|
||||
.dstBinding = 0,
|
||||
.dstBinding = @intCast(i),
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = vk.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.pBufferInfo = &buffer_descriptor,
|
||||
.pBufferInfo = &buffer_descriptors[i],
|
||||
};
|
||||
write_count += 1;
|
||||
}
|
||||
|
|
@ -472,7 +510,7 @@ pub fn init(
|
|||
writes[write_count] = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self.descriptor_sets[frame],
|
||||
.dstBinding = @intCast(i + 1),
|
||||
.dstBinding = @intCast(config.uniforms.len + i),
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = vk.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
|
|
@ -514,6 +552,7 @@ pub fn deinit(self: *Self) void {
|
|||
vk.vkDestroyPipeline(self.device.raw, raw, null);
|
||||
}
|
||||
self.alloc.free(self.uniforms);
|
||||
self.alloc.free(self.uniform_offsets);
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -521,7 +560,7 @@ pub fn deinit(self: *Self) void {
|
|||
/// ----------------------------------------------------
|
||||
pub fn setUniform(self: *Self, name: []const u8, value: anytype) !void {
|
||||
const uniform_memory = self.uniform_memories[self.vulkan.current_frame];
|
||||
for (self.uniforms) |uniform| {
|
||||
for (self.uniforms, 0..) |uniform, i| {
|
||||
if (std.mem.eql(u8, uniform.name, name)) {
|
||||
if (@sizeOf(@TypeOf(value)) > uniform.size) {
|
||||
return error.UniformSizeMismatch;
|
||||
|
|
@ -531,7 +570,7 @@ pub fn setUniform(self: *Self, name: []const u8, value: anytype) !void {
|
|||
if (vk.vkMapMemory(
|
||||
self.device.raw,
|
||||
uniform_memory,
|
||||
uniform.offset,
|
||||
self.uniform_offsets[i],
|
||||
uniform.size,
|
||||
0,
|
||||
&mapped,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const Self = @This();
|
|||
// FIELDS
|
||||
//
|
||||
|
||||
raw: *vk.VkShaderModule_T,
|
||||
raw: vk.VkShaderModule,
|
||||
device: *const Device,
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
@ -40,7 +40,10 @@ pub fn init(
|
|||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(self: *Self) void {
|
||||
vk.vkDestroyShaderModule(self.device.raw, self.raw, null);
|
||||
if (self.raw) |raw| {
|
||||
vk.vkDestroyShaderModule(self.device.raw, raw, null);
|
||||
self.raw = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ raw: *vk.VkSwapchainKHR_T,
|
|||
images: []vk.VkImage,
|
||||
image_views: []vk.VkImageView,
|
||||
|
||||
depth_images: []vk.VkImage = &.{},
|
||||
depth_memories: []vk.VkDeviceMemory = &.{},
|
||||
depth_views: []vk.VkImageView = &.{},
|
||||
depth_format: vk.VkFormat = vk.VK_FORMAT_UNDEFINED,
|
||||
|
||||
format: vk.VkFormat,
|
||||
extent: vk.VkExtent2D,
|
||||
|
||||
|
|
@ -158,6 +163,8 @@ pub fn init(
|
|||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.destroyDepth();
|
||||
|
||||
for (self.image_views) |view| {
|
||||
vk.vkDestroyImageView(self.device.raw, view, null);
|
||||
}
|
||||
|
|
@ -167,3 +174,164 @@ pub fn deinit(self: *Self) void {
|
|||
self.alloc.free(self.images);
|
||||
self.alloc.free(self.image_views);
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn ensureDepth(self: *Self, format: vk.VkFormat) !void {
|
||||
if (self.depth_format == format and self.depth_views.len > 0) return;
|
||||
|
||||
self.destroyDepth();
|
||||
|
||||
const count = self.images.len;
|
||||
const images = try self.alloc.alloc(vk.VkImage, count);
|
||||
errdefer self.alloc.free(images);
|
||||
const memories = try self.alloc.alloc(vk.VkDeviceMemory, count);
|
||||
errdefer self.alloc.free(memories);
|
||||
const views = try self.alloc.alloc(vk.VkImageView, count);
|
||||
|
||||
var created: usize = 0;
|
||||
errdefer {
|
||||
for (0..created) |i| {
|
||||
if (views[i]) |view| vk.vkDestroyImageView(self.device.raw, view, null);
|
||||
if (memories[i]) |memory| vk.vkFreeMemory(self.device.raw, memory, null);
|
||||
if (images[i]) |image| vk.vkDestroyImage(self.device.raw, image, null);
|
||||
}
|
||||
self.alloc.free(views);
|
||||
}
|
||||
|
||||
const aspect: vk.VkImageAspectFlags = if (isDepthStencilFormat(format))
|
||||
vk.VK_IMAGE_ASPECT_DEPTH_BIT | vk.VK_IMAGE_ASPECT_STENCIL_BIT
|
||||
else
|
||||
vk.VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
const image_info: vk.VkImageCreateInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = vk.VK_IMAGE_TYPE_2D,
|
||||
.extent = .{
|
||||
.width = self.extent.width,
|
||||
.height = self.extent.height,
|
||||
.depth = 1,
|
||||
},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.format = format,
|
||||
.tiling = vk.VK_IMAGE_TILING_OPTIMAL,
|
||||
.initialLayout = vk.VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.usage = vk.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
.samples = vk.VK_SAMPLE_COUNT_1_BIT,
|
||||
.sharingMode = vk.VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
|
||||
for (0..count) |i| {
|
||||
created = i;
|
||||
|
||||
if (vk.vkCreateImage(self.device.raw, &image_info, null, &images[i]) != vk.VK_SUCCESS) {
|
||||
return error.FailedToCreateDepthImage;
|
||||
}
|
||||
|
||||
var mem_req: vk.VkMemoryRequirements = .{};
|
||||
vk.vkGetImageMemoryRequirements(self.device.raw, images[i], &mem_req);
|
||||
|
||||
const mem_type = findMemoryType(
|
||||
self.device.physical_device,
|
||||
mem_req.memoryTypeBits,
|
||||
vk.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
) orelse return error.FailedToFindSuitableMemoryType;
|
||||
|
||||
const alloc_info: vk.VkMemoryAllocateInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = mem_req.size,
|
||||
.memoryTypeIndex = mem_type,
|
||||
};
|
||||
if (vk.vkAllocateMemory(self.device.raw, &alloc_info, null, &memories[i]) != vk.VK_SUCCESS) {
|
||||
return error.FailedToAllocateDepthMemory;
|
||||
}
|
||||
_ = vk.vkBindImageMemory(self.device.raw, images[i], memories[i], 0);
|
||||
|
||||
const view_info: vk.VkImageViewCreateInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.image = images[i],
|
||||
.viewType = vk.VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = format,
|
||||
.components = .{
|
||||
.r = vk.VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = vk.VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = vk.VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = vk.VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
},
|
||||
.subresourceRange = .{
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
};
|
||||
if (vk.vkCreateImageView(self.device.raw, &view_info, null, &views[i]) != vk.VK_SUCCESS) {
|
||||
return error.FailedToCreateDepthImageView;
|
||||
}
|
||||
|
||||
created = i + 1;
|
||||
}
|
||||
|
||||
self.depth_images = images;
|
||||
self.depth_memories = memories;
|
||||
self.depth_views = views;
|
||||
self.depth_format = format;
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn destroyDepth(self: *Self) void {
|
||||
if (self.depth_views.len > 0) {
|
||||
for (self.depth_views) |view| {
|
||||
if (view) |v| vk.vkDestroyImageView(self.device.raw, v, null);
|
||||
}
|
||||
self.alloc.free(self.depth_views);
|
||||
self.depth_views = &.{};
|
||||
}
|
||||
if (self.depth_memories.len > 0) {
|
||||
for (self.depth_memories) |memory| {
|
||||
if (memory) |m| vk.vkFreeMemory(self.device.raw, m, null);
|
||||
}
|
||||
self.alloc.free(self.depth_memories);
|
||||
self.depth_memories = &.{};
|
||||
}
|
||||
if (self.depth_images.len > 0) {
|
||||
for (self.depth_images) |image| {
|
||||
if (image) |im| vk.vkDestroyImage(self.device.raw, im, null);
|
||||
}
|
||||
self.alloc.free(self.depth_images);
|
||||
self.depth_images = &.{};
|
||||
}
|
||||
self.depth_format = vk.VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn isDepthStencilFormat(format: vk.VkFormat) bool {
|
||||
return format == vk.VK_FORMAT_D16_UNORM_S8_UINT or
|
||||
format == vk.VK_FORMAT_D24_UNORM_S8_UINT or
|
||||
format == vk.VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
fn findMemoryType(
|
||||
physical_device: vk.VkPhysicalDevice,
|
||||
type_bits: u32,
|
||||
properties: vk.VkMemoryPropertyFlags,
|
||||
) ?u32 {
|
||||
var mem_props: vk.VkPhysicalDeviceMemoryProperties = .{};
|
||||
vk.vkGetPhysicalDeviceMemoryProperties(physical_device, &mem_props);
|
||||
|
||||
for (0..mem_props.memoryTypeCount) |i| {
|
||||
if ((type_bits & (@as(u32, 1) << @intCast(i))) != 0 and
|
||||
(mem_props.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
{
|
||||
return @intCast(i);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! ----------------------------------------------------
|
||||
//! `🗲` Vulkan RHI `🗲`
|
||||
//! 😭 Send Help 😭
|
||||
//! ----------------------------------------------------
|
||||
|
||||
const std = @import("std");
|
||||
|
|
@ -44,6 +45,16 @@ const Texture = common.Texture;
|
|||
// --- # ---
|
||||
pub const MAX_FRAMES_IN_FLIGHT: usize = 3;
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn depthFormatToVk(format: common.DepthFormat) vk.VkFormat {
|
||||
return switch (format) {
|
||||
.d16_unorm => vk.VK_FORMAT_D16_UNORM,
|
||||
.d24_unorm_s8 => vk.VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
.d32_sfloat => vk.VK_FORMAT_D32_SFLOAT,
|
||||
};
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const Frame = struct {
|
||||
|
|
@ -419,7 +430,7 @@ pub fn endFrame(
|
|||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn beginRendering(
|
||||
pub fn beginPass(
|
||||
self: *Self,
|
||||
swapchain: Handle(Swapchain),
|
||||
config: RenderPassConfig,
|
||||
|
|
@ -474,6 +485,79 @@ pub fn beginRendering(
|
|||
&barrier,
|
||||
);
|
||||
|
||||
var depth_attachment: vk.VkRenderingAttachmentInfo = undefined;
|
||||
if (config.depth_enabled) {
|
||||
const depth_format = depthFormatToVk(config.depth_format);
|
||||
try raw_swapchain.ensureDepth(depth_format);
|
||||
|
||||
const depth_aspect: vk.VkImageAspectFlags = if (config.depth_format == .d24_unorm_s8)
|
||||
vk.VK_IMAGE_ASPECT_DEPTH_BIT | vk.VK_IMAGE_ASPECT_STENCIL_BIT
|
||||
else
|
||||
vk.VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
const depth_barrier: vk.VkImageMemoryBarrier = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
|
||||
.oldLayout = vk.VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
|
||||
.srcQueueFamilyIndex = vk.VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = vk.VK_QUEUE_FAMILY_IGNORED,
|
||||
|
||||
.image = raw_swapchain.depth_images[frame.image_index],
|
||||
|
||||
.subresourceRange = .{
|
||||
.aspectMask = depth_aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
};
|
||||
|
||||
vk.vkCmdPipelineBarrier(
|
||||
frame.cmd_buf,
|
||||
|
||||
vk.VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk.VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
|
||||
0,
|
||||
|
||||
0,
|
||||
null,
|
||||
|
||||
0,
|
||||
null,
|
||||
|
||||
1,
|
||||
&depth_barrier,
|
||||
);
|
||||
|
||||
depth_attachment = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = raw_swapchain.depth_views[frame.image_index],
|
||||
.imageLayout = vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
.loadOp = switch (config.depth_load_op) {
|
||||
.clear => vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.load => vk.VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.dont_care => vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
},
|
||||
.storeOp = switch (config.depth_store_op) {
|
||||
.store => vk.VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.dont_care => vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
},
|
||||
.clearValue = .{
|
||||
.depthStencil = .{
|
||||
.depth = config.clear_depth,
|
||||
.stencil = @intCast(config.clear_stencil),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const color_attachment: vk.VkRenderingAttachmentInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = raw_swapchain.image_views[frame.image_index],
|
||||
|
|
@ -494,7 +578,7 @@ pub fn beginRendering(
|
|||
},
|
||||
};
|
||||
|
||||
const rendering_info: vk.VkRenderingInfo = .{
|
||||
var rendering_info: vk.VkRenderingInfo = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea = .{
|
||||
.offset = .{
|
||||
|
|
@ -507,6 +591,9 @@ pub fn beginRendering(
|
|||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_attachment,
|
||||
};
|
||||
if (config.depth_enabled) {
|
||||
rendering_info.pDepthAttachment = &depth_attachment;
|
||||
}
|
||||
|
||||
vk.vkCmdBeginRendering(
|
||||
frame.cmd_buf,
|
||||
|
|
@ -536,7 +623,7 @@ pub fn beginRendering(
|
|||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
pub fn endRendering(
|
||||
pub fn endPass(
|
||||
self: *Self,
|
||||
swapchain: Handle(Swapchain),
|
||||
) void {
|
||||
|
|
|
|||
28
src/vendor/fast_obj/fast_obj.c
vendored
Normal file
28
src/vendor/fast_obj/fast_obj.c
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 Richard Knight
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define FAST_OBJ_IMPLEMENTATION
|
||||
#include "fast_obj.h"
|
||||
1357
src/vendor/fast_obj/fast_obj.h
vendored
Normal file
1357
src/vendor/fast_obj/fast_obj.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
Loading…
Add table
Reference in a new issue