mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Merge 830ef09dd6d6e9393a40ca62cc601cfa06972573 into 2dc2a6e79018221d5aab44e09be242d9dab3ddf2
This commit is contained in:
commit
b2aca13cad
@ -56,9 +56,11 @@ fn linkLibraries(b: *std.Build, exe: *std.Build.Step.Compile, useLocalDeps: bool
|
||||
exe.linkSystemLibrary("gdi32");
|
||||
exe.linkSystemLibrary("opengl32");
|
||||
exe.linkSystemLibrary("ws2_32");
|
||||
exe.linkSystemLibrary("vulkan-1");
|
||||
} else if(t.os.tag == .linux) {
|
||||
exe.linkSystemLibrary("X11");
|
||||
exe.linkSystemLibrary("GL");
|
||||
exe.linkSystemLibrary("vulkan");
|
||||
} else if(t.os.tag == .macos) {
|
||||
exe.linkFramework("AudioUnit");
|
||||
exe.linkFramework("AudioToolbox");
|
||||
@ -71,6 +73,7 @@ fn linkLibraries(b: *std.Build, exe: *std.Build.Step.Compile, useLocalDeps: bool
|
||||
exe.addRPath(.{.cwd_relative = "/usr/local/GL/lib"});
|
||||
exe.root_module.addRPathSpecial("@executable_path/../Library");
|
||||
exe.addRPath(.{.cwd_relative = "/opt/X11/lib"});
|
||||
exe.linkSystemLibrary("vulkan.1");
|
||||
} else {
|
||||
std.log.err("Unsupported target: {}\n", .{t.os.tag});
|
||||
}
|
||||
|
@ -7,8 +7,11 @@ const files = main.files;
|
||||
const vec = main.vec;
|
||||
const Vec2f = vec.Vec2f;
|
||||
|
||||
const vulkan = @import("vulkan.zig");
|
||||
|
||||
pub const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cDefine("GLFW_INCLUDE_VULKAN", "");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
@ -640,6 +643,12 @@ pub fn init() void { // MARK: init()
|
||||
@panic("Failed to initialize GLFW");
|
||||
}
|
||||
|
||||
if(c.glfwVulkanSupported() == c.GLFW_FALSE) {
|
||||
std.log.err("Vulkan is not supported. Please update your drivers if you want to keep playing Cubyz in the future.", .{});
|
||||
}
|
||||
|
||||
vulkan.Instance.init();
|
||||
|
||||
c.glfwWindowHint(c.GLFW_OPENGL_DEBUG_CONTEXT, 1);
|
||||
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
@ -683,6 +692,7 @@ pub fn init() void { // MARK: init()
|
||||
pub fn deinit() void {
|
||||
Gamepad.deinit();
|
||||
c.glfwDestroyWindow(window);
|
||||
vulkan.Instance.deinit();
|
||||
c.glfwTerminate();
|
||||
}
|
||||
var cursorVisible: bool = true;
|
||||
|
153
src/graphics/vulkan.zig
Normal file
153
src/graphics/vulkan.zig
Normal file
@ -0,0 +1,153 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const c = main.Window.c;
|
||||
|
||||
const Errors = struct { // MARK: Errors
|
||||
pub const VK_SUCCESS: c_int = 0;
|
||||
pub const VK_NOT_READY: c_int = 1;
|
||||
pub const VK_TIMEOUT: c_int = 2;
|
||||
pub const VK_EVENT_SET: c_int = 3;
|
||||
pub const VK_EVENT_RESET: c_int = 4;
|
||||
pub const VK_INCOMPLETE: c_int = 5;
|
||||
pub const VK_ERROR_OUT_OF_HOST_MEMORY: c_int = -1;
|
||||
pub const VK_ERROR_OUT_OF_DEVICE_MEMORY: c_int = -2;
|
||||
pub const VK_ERROR_INITIALIZATION_FAILED: c_int = -3;
|
||||
pub const VK_ERROR_DEVICE_LOST: c_int = -4;
|
||||
pub const VK_ERROR_MEMORY_MAP_FAILED: c_int = -5;
|
||||
pub const VK_ERROR_LAYER_NOT_PRESENT: c_int = -6;
|
||||
pub const VK_ERROR_EXTENSION_NOT_PRESENT: c_int = -7;
|
||||
pub const VK_ERROR_FEATURE_NOT_PRESENT: c_int = -8;
|
||||
pub const VK_ERROR_INCOMPATIBLE_DRIVER: c_int = -9;
|
||||
pub const VK_ERROR_TOO_MANY_OBJECTS: c_int = -10;
|
||||
pub const VK_ERROR_FORMAT_NOT_SUPPORTED: c_int = -11;
|
||||
pub const VK_ERROR_FRAGMENTED_POOL: c_int = -12;
|
||||
pub const VK_ERROR_UNKNOWN: c_int = -13;
|
||||
pub const VK_ERROR_OUT_OF_POOL_MEMORY: c_int = -1000069000;
|
||||
pub const VK_ERROR_INVALID_EXTERNAL_HANDLE: c_int = -1000072003;
|
||||
pub const VK_ERROR_FRAGMENTATION: c_int = -1000161000;
|
||||
pub const VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: c_int = -1000257000;
|
||||
pub const VK_PIPELINE_COMPILE_REQUIRED: c_int = 1000297000;
|
||||
pub const VK_ERROR_NOT_PERMITTED: c_int = -1000174001;
|
||||
pub const VK_ERROR_SURFACE_LOST_KHR: c_int = -1000000000;
|
||||
pub const VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: c_int = -1000000001;
|
||||
pub const VK_SUBOPTIMAL_KHR: c_int = 1000001003;
|
||||
pub const VK_ERROR_OUT_OF_DATE_KHR: c_int = -1000001004;
|
||||
pub const VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: c_int = -1000003001;
|
||||
pub const VK_ERROR_VALIDATION_FAILED_EXT: c_int = -1000011001;
|
||||
pub const VK_ERROR_INVALID_SHADER_NV: c_int = -1000012000;
|
||||
pub const VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR: c_int = -1000023000;
|
||||
pub const VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR: c_int = -1000023001;
|
||||
pub const VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR: c_int = -1000023002;
|
||||
pub const VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR: c_int = -1000023003;
|
||||
pub const VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR: c_int = -1000023004;
|
||||
pub const VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR: c_int = -1000023005;
|
||||
pub const VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: c_int = -1000158000;
|
||||
pub const VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: c_int = -1000255000;
|
||||
pub const VK_THREAD_IDLE_KHR: c_int = 1000268000;
|
||||
pub const VK_THREAD_DONE_KHR: c_int = 1000268001;
|
||||
pub const VK_OPERATION_DEFERRED_KHR: c_int = 1000268002;
|
||||
pub const VK_OPERATION_NOT_DEFERRED_KHR: c_int = 1000268003;
|
||||
pub const VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR: c_int = -1000299000;
|
||||
pub const VK_ERROR_COMPRESSION_EXHAUSTED_EXT: c_int = -1000338000;
|
||||
pub const VK_INCOMPATIBLE_SHADER_BINARY_EXT: c_int = 1000482000;
|
||||
pub const VK_PIPELINE_BINARY_MISSING_KHR: c_int = 1000483000;
|
||||
pub const VK_ERROR_NOT_ENOUGH_SPACE_KHR: c_int = -1000483000;
|
||||
pub const VK_ERROR_OUT_OF_POOL_MEMORY_KHR: c_int = -1000069000;
|
||||
pub const VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR: c_int = -1000072003;
|
||||
pub const VK_ERROR_FRAGMENTATION_EXT: c_int = -1000161000;
|
||||
pub const VK_ERROR_NOT_PERMITTED_EXT: c_int = -1000174001;
|
||||
pub const VK_ERROR_NOT_PERMITTED_KHR: c_int = -1000174001;
|
||||
pub const VK_ERROR_INVALID_DEVICE_ADDRESS_EXT: c_int = -1000257000;
|
||||
pub const VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR: c_int = -1000257000;
|
||||
pub const VK_PIPELINE_COMPILE_REQUIRED_EXT: c_int = 1000297000;
|
||||
pub const VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT: c_int = 1000297000;
|
||||
pub const VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT: c_int = 1000482000;
|
||||
pub const VK_RESULT_MAX_ENUM: c_int = 2147483647;
|
||||
};
|
||||
|
||||
fn checkResult(result: c.VkResult) void {
|
||||
if(result != c.VK_SUCCESS) {
|
||||
inline for(@typeInfo(Errors).@"struct".decls) |decl| {
|
||||
if(result == @field(c, decl.name)) {
|
||||
std.log.err("Encountered a vulkan error: {s}", .{decl.name});
|
||||
return;
|
||||
}
|
||||
}
|
||||
std.log.err("Encountered a vulkan error with unknown error code {}", .{result});
|
||||
}
|
||||
}
|
||||
|
||||
fn fakeCheckResult(result: anytype) void {
|
||||
if(@TypeOf(result) != void) {
|
||||
checkResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
fn allocEnumeration(function: anytype, allocator: main.heap.NeverFailingAllocator, args: anytype) []@typeInfo(@typeInfo(@TypeOf(function)).@"fn".params[@typeInfo(@TypeOf(function)).@"fn".params.len - 1].type.?).pointer.child {
|
||||
const T = @typeInfo(@typeInfo(@TypeOf(function)).@"fn".params[@typeInfo(@TypeOf(function)).@"fn".params.len - 1].type.?).pointer.child;
|
||||
var count: u32 = 0;
|
||||
fakeCheckResult(@call(.auto, function, args ++ .{&count, null}));
|
||||
const list = allocator.alloc(T, count);
|
||||
fakeCheckResult(@call(.auto, function, args ++ .{&count, list.ptr}));
|
||||
return list;
|
||||
}
|
||||
|
||||
pub const Instance = struct { // MARK: Instance
|
||||
var instance: c.VkInstance = undefined;
|
||||
|
||||
const validationLayers: []const [*:0]const u8 = &.{
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
};
|
||||
|
||||
fn checkValidationLayerSupport() bool {
|
||||
const availableLayers: []c.VkLayerProperties = allocEnumeration(c.vkEnumerateInstanceLayerProperties, main.stackAllocator, .{});
|
||||
defer main.stackAllocator.free(availableLayers);
|
||||
for(validationLayers) |layerName| continueOuter: {
|
||||
for(availableLayers) |layerProperties| {
|
||||
if(std.mem.eql(u8, std.mem.span(layerName), std.mem.span(@as([*:0]const u8, @ptrCast(&layerProperties.layerName))))) {
|
||||
break :continueOuter;
|
||||
}
|
||||
}
|
||||
std.log.err("Couldn't find validation layer {s}", .{layerName});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn init() void {
|
||||
const appInfo = c.VkApplicationInfo {
|
||||
.sType = c.VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pApplicationName = "Cubyz",
|
||||
.applicationVersion = c.VK_MAKE_VERSION(0, 0, 0),
|
||||
.pEngineName = "custom",
|
||||
.engineVersion = c.VK_MAKE_VERSION(0, 0, 0),
|
||||
.apiVersion = c.VK_API_VERSION_1_3,
|
||||
};
|
||||
var glfwExtensionCount: u32 = 0;
|
||||
const glfwExtensions: [*c][*c]const u8 = c.glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||
|
||||
const availableExtensions: []c.VkExtensionProperties = allocEnumeration(c.vkEnumerateInstanceExtensionProperties, main.stackAllocator, .{null});
|
||||
defer main.stackAllocator.free(availableExtensions);
|
||||
std.log.debug("Availabe vulkan instance extensions:", .{});
|
||||
for(availableExtensions) |ext| {
|
||||
std.log.debug("\t{s}", .{ext.extensionName});
|
||||
}
|
||||
|
||||
const createInfo = c.VkInstanceCreateInfo {
|
||||
.sType = c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pApplicationInfo = &appInfo,
|
||||
.enabledExtensionCount = glfwExtensionCount,
|
||||
.ppEnabledExtensionNames = glfwExtensions,
|
||||
.ppEnabledLayerNames = validationLayers.ptr,
|
||||
.enabledLayerCount = if(checkValidationLayerSupport()) validationLayers.len else 0,
|
||||
};
|
||||
// TODO: Use the debug callback when validation layers are enabled to write messages into the logger.
|
||||
// https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/00_Setup/02_Validation_layers.html#_message_callback
|
||||
checkResult(c.vkCreateInstance(&createInfo, null, &instance));
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
c.vkDestroyInstance(instance, null);
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user