From 9f713edf62820e3df1ba6b105745a0332aa2ab6b Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Tue, 20 May 2025 13:23:05 +0200 Subject: [PATCH] Fixes + Refactor --- .envrc | 3 +- README.md | 5 +++ flake.lock | 25 +++++++++++ flake.nix | 35 ++++++++++----- pom.xml | 11 ++--- .../java/fr/mrdev023/vulkan_java/App.java | 12 ++++- .../vulkan_java/{renderer => vk}/Device.java | 45 ++++++++++++------- .../{renderer => vk}/Instance.java | 17 ++++--- .../{renderer => vk}/PhysicalDevice.java | 20 +++++---- .../vulkan_java/{renderer => vk}/Queue.java | 2 +- .../vulkan_java/{renderer => vk}/Surface.java | 22 ++++----- .../vulkan_java/{renderer => vk}/Vulkan.java | 4 +- .../mrdev023/vulkan_java/vk/VulkanError.java | 39 ++++++++++++++++ .../{renderer => vk}/VulkanUtils.java | 16 ++----- .../mrdev023/vulkan_java/window/Display.java | 32 +++++++------ .../fr/mrdev023/vulkan_java/window/Input.java | 9 ++-- src/main/resources/tinylog.properties | 2 + 17 files changed, 206 insertions(+), 93 deletions(-) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/Device.java (69%) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/Instance.java (95%) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/PhysicalDevice.java (92%) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/Queue.java (97%) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/Surface.java (69%) rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/Vulkan.java (92%) create mode 100644 src/main/java/fr/mrdev023/vulkan_java/vk/VulkanError.java rename src/main/java/fr/mrdev023/vulkan_java/{renderer => vk}/VulkanUtils.java (60%) create mode 100644 src/main/resources/tinylog.properties diff --git a/.envrc b/.envrc index e3fecb3..2f8e1d3 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1 @@ -use flake - +use flake --impure diff --git a/README.md b/README.md index d533ef3..ad1eb06 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Project +## Info + +Extensions used : ` +vscjava.vscode-java-pack` + ## Usefull command 1. Compile diff --git a/flake.lock b/flake.lock index ade8d2e..0207aaf 100644 --- a/flake.lock +++ b/flake.lock @@ -18,6 +18,30 @@ "type": "github" } }, + "nixgl": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735283791, + "narHash": "sha256-JlT4VFs8aVlW+l151HZIZumfFsccZXcO/k5WpbYF09Y=", + "owner": "phirsch", + "repo": "nixGL", + "rev": "ea8baea3b9d854bf9cf5c834a805c50948dd2603", + "type": "github" + }, + "original": { + "owner": "phirsch", + "ref": "fix-versionMatch", + "repo": "nixGL", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1728538411, @@ -37,6 +61,7 @@ "root": { "inputs": { "flake-utils": "flake-utils", + "nixgl": "nixgl", "nixpkgs": "nixpkgs" } }, diff --git a/flake.nix b/flake.nix index da8ae80..729fce5 100644 --- a/flake.nix +++ b/flake.nix @@ -4,26 +4,39 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-utils.url = "github:numtide/flake-utils"; + nixgl = { + # Revert this to community version when https://github.com/nix-community/nixGL/pull/187 is merged + url = "github:phirsch/nixGL/fix-versionMatch"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + }; }; - outputs = { self, nixpkgs, flake-utils }: + outputs = { nixpkgs, flake-utils, nixgl, ... }: flake-utils.lib.eachSystem flake-utils.lib.allSystems (system: let - pkgs = import nixpkgs { inherit system; }; + overlays = [ nixgl.overlay ]; + pkgs = import nixpkgs { + inherit system overlays; + config.allowUnfree = true; + }; buildInputs = with pkgs; [ vulkan-headers vulkan-loader vulkan-validation-layers renderdoc ]; + + mkCustomShell = { extraPkgs ? [] }: pkgs.mkShell { + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; + VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d:${pkgs.renderdoc}/share/vulkan/implicit_layer.d"; + + packages = with pkgs; [ + jdk22 + maven + ] ++ extraPkgs; + }; in { devShells = { - default = pkgs.mkShell { - LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; - VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d:${pkgs.renderdoc}/share/vulkan/implicit_layer.d"; - - packages = with pkgs; [ - jdk22 - maven - ]; - }; + default = mkCustomShell { extraPkgs = [ pkgs.nixgl.auto.nixVulkanNvidia pkgs.nixgl.nixVulkanMesa ]; }; + nixos = mkCustomShell {}; }; }); } diff --git a/pom.xml b/pom.xml index 735d74d..a6c414e 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 21 3.13.0 3.6.0 + 3.1.0 3.3.6 1.10.8 2.7.0 @@ -204,11 +205,11 @@ - src + src/main/java - - res - + + src/main/resources + @@ -218,7 +219,7 @@ org.codehaus.mojo exec-maven-plugin - 3.1.0 + ${maven-mojo-exec-plugin.version} ${main.class} diff --git a/src/main/java/fr/mrdev023/vulkan_java/App.java b/src/main/java/fr/mrdev023/vulkan_java/App.java index 0b76f45..acf70c8 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/App.java +++ b/src/main/java/fr/mrdev023/vulkan_java/App.java @@ -1,6 +1,9 @@ package fr.mrdev023.vulkan_java; -import fr.mrdev023.vulkan_java.renderer.Vulkan; +import org.tinylog.Logger; + +import fr.mrdev023.vulkan_java.vk.Vulkan; +import fr.mrdev023.vulkan_java.vk.VulkanError; import fr.mrdev023.vulkan_java.window.Display; import fr.mrdev023.vulkan_java.window.Input; @@ -9,7 +12,12 @@ public class App { Display.create("My first application", 800, 600); Display.printMonitorsInfo(); Input.init(); - Vulkan.init(); + try { + Vulkan.init(); + } catch (VulkanError e) { + Logger.error(e.getMessage()); + System.exit(1); + } while (!Display.isCloseRequested()) { Display.updateEvent(); diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/Device.java b/src/main/java/fr/mrdev023/vulkan_java/vk/Device.java similarity index 69% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/Device.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/Device.java index 8e9e3e3..a527d0b 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/Device.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/Device.java @@ -1,4 +1,4 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; @@ -8,8 +8,7 @@ import org.tinylog.Logger; import java.nio.*; import java.util.*; -import static fr.mrdev023.vulkan_java.renderer.VulkanUtils.vkCheck; -import static org.lwjgl.vulkan.KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME; +import static fr.mrdev023.vulkan_java.vk.VulkanError.vkCheck; import static org.lwjgl.vulkan.VK11.*; public class Device { @@ -17,20 +16,21 @@ public class Device { private final PhysicalDevice physicalDevice; private final VkDevice vkDevice; - public Device(PhysicalDevice physicalDevice) { - Logger.debug("Creating device"); - + public Device(PhysicalDevice physicalDevice) throws VulkanError { this.physicalDevice = physicalDevice; - try (MemoryStack stack = MemoryStack.stackPush()) { + try (MemoryStack stack = MemoryStack.stackPush()) { // Define required extensions Set deviceExtensions = getDeviceExtensions(); - boolean usePortability = deviceExtensions.contains(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) && VulkanUtils.getOS() == VulkanUtils.OSType.MACOS; + boolean usePortability = deviceExtensions + .contains(KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) + && VulkanUtils.getOS() == VulkanUtils.OSType.MACOS; + int numExtensions = usePortability ? 2 : 1; PointerBuffer requiredExtensions = stack.mallocPointer(numExtensions); requiredExtensions.put(stack.ASCII(KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME)); if (usePortability) { - requiredExtensions.put(stack.ASCII(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)); + requiredExtensions.put(stack.ASCII(KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)); } requiredExtensions.flip(); @@ -40,7 +40,8 @@ public class Device { // Enable all the queue families VkQueueFamilyProperties.Buffer queuePropsBuff = physicalDevice.getVkQueueFamilyProps(); int numQueuesFamilies = queuePropsBuff.capacity(); - VkDeviceQueueCreateInfo.Buffer queueCreationInfoBuf = VkDeviceQueueCreateInfo.calloc(numQueuesFamilies, stack); + VkDeviceQueueCreateInfo.Buffer queueCreationInfoBuf = VkDeviceQueueCreateInfo.calloc(numQueuesFamilies, + stack); for (int i = 0; i < numQueuesFamilies; i++) { FloatBuffer priorities = stack.callocFloat(queuePropsBuff.get(i).queueCount()); queueCreationInfoBuf.get(i) @@ -60,6 +61,8 @@ public class Device { "Failed to create device"); vkDevice = new VkDevice(pp.get(0), physicalDevice.getVkPhysicalDevice(), deviceCreateInfo); } + + Logger.debug("Vulkan device created"); } public void destroy() { @@ -67,21 +70,31 @@ public class Device { vkDestroyDevice(vkDevice, null); } - private Set getDeviceExtensions() { + private Set getDeviceExtensions() throws VulkanError { Set deviceExtensions = new HashSet<>(); try (MemoryStack stack = MemoryStack.stackPush()) { + // Get the number of device extensions IntBuffer numExtensionsBuf = stack.callocInt(1); - vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, null); - int numExtensions = numExtensionsBuf.get(0); - Logger.debug("Device supports [{}] extensions", numExtensions); + int result = vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null, + numExtensionsBuf, + null); + vkCheck(result, "Failed to enumerate device extension properties"); + int numExtensions = numExtensionsBuf.get(0); + Logger.debug("Vulkan device supported extensions ({}):", numExtensions); + + // Get the device extensions VkExtensionProperties.Buffer propsBuff = VkExtensionProperties.calloc(numExtensions, stack); - vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff); + result = vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null, + numExtensionsBuf, + propsBuff); + vkCheck(result, "Failed to enumerate device extension properties"); + for (int i = 0; i < numExtensions; i++) { VkExtensionProperties props = propsBuff.get(i); String extensionName = props.extensionNameString(); deviceExtensions.add(extensionName); - Logger.debug("Supported device extension [{}]", extensionName); + Logger.debug("\t - {}", extensionName); } } return deviceExtensions; diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/Instance.java b/src/main/java/fr/mrdev023/vulkan_java/vk/Instance.java similarity index 95% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/Instance.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/Instance.java index 6bf1879..ecdd177 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/Instance.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/Instance.java @@ -1,4 +1,4 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import org.lwjgl.PointerBuffer; import org.lwjgl.glfw.GLFWVulkan; @@ -9,7 +9,7 @@ import org.tinylog.Logger; import java.nio.*; import java.util.*; -import static fr.mrdev023.vulkan_java.renderer.VulkanUtils.vkCheck; +import static fr.mrdev023.vulkan_java.vk.VulkanError.vkCheck; import static org.lwjgl.vulkan.EXTDebugUtils.*; import static org.lwjgl.vulkan.KHRPortabilityEnumeration.VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; import static org.lwjgl.vulkan.VK11.*; @@ -28,7 +28,7 @@ public class Instance { private VkDebugUtilsMessengerCreateInfoEXT debugUtils; private long vkDebugHandle; - public Instance(boolean validate) { + public Instance(boolean validate) throws VulkanError { Logger.debug("Creating Vulkan instance"); try (MemoryStack stack = MemoryStack.stackPush()) { // Create application information @@ -47,11 +47,12 @@ public class Instance { boolean supportsValidation = validate; if (validate && numValidationLayers == 0) { supportsValidation = false; - Logger.warn("Request validation but no supported validation layers found. Falling back to no validation"); + Logger.warn( + "Request validation but no supported validation layers found. Falling back to no validation"); } Logger.debug("Validation: {}", supportsValidation); - // Set required layers + // Set required layers PointerBuffer requiredLayers = null; if (supportsValidation) { requiredLayers = stack.mallocPointer(numValidationLayers); @@ -115,7 +116,8 @@ public class Instance { vkDebugHandle = VK_NULL_HANDLE; if (supportsValidation) { LongBuffer longBuff = stack.mallocLong(1); - vkCheck(vkCreateDebugUtilsMessengerEXT(vkInstance, debugUtils, null, longBuff), "Error creating debug utils"); + vkCheck(vkCreateDebugUtilsMessengerEXT(vkInstance, debugUtils, null, longBuff), + "Error creating debug utils"); vkDebugHandle = longBuff.get(0); } } @@ -128,7 +130,8 @@ public class Instance { .messageSeverity(MESSAGE_SEVERITY_BITMASK) .messageType(MESSAGE_TYPE_BITMASK) .pfnUserCallback((messageSeverity, messageTypes, pCallbackData, pUserData) -> { - VkDebugUtilsMessengerCallbackDataEXT callbackData = VkDebugUtilsMessengerCallbackDataEXT.create(pCallbackData); + VkDebugUtilsMessengerCallbackDataEXT callbackData = VkDebugUtilsMessengerCallbackDataEXT + .create(pCallbackData); if ((messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) { Logger.info("VkDebugUtilsCallback, {}", callbackData.pMessageString()); } else if ((messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) { diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/PhysicalDevice.java b/src/main/java/fr/mrdev023/vulkan_java/vk/PhysicalDevice.java similarity index 92% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/PhysicalDevice.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/PhysicalDevice.java index 1f3a169..1b67ced 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/PhysicalDevice.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/PhysicalDevice.java @@ -1,4 +1,4 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; @@ -8,7 +8,7 @@ import org.tinylog.Logger; import java.nio.IntBuffer; import java.util.*; -import static fr.mrdev023.vulkan_java.renderer.VulkanUtils.vkCheck; +import static fr.mrdev023.vulkan_java.vk.VulkanError.vkCheck; import static org.lwjgl.vulkan.VK11.*; public class PhysicalDevice { @@ -20,7 +20,7 @@ public class PhysicalDevice { private final VkPhysicalDeviceProperties vkPhysicalDeviceProperties; private final VkQueueFamilyProperties.Buffer vkQueueFamilyProps; - private PhysicalDevice(VkPhysicalDevice vkPhysicalDevice) { + private PhysicalDevice(VkPhysicalDevice vkPhysicalDevice) throws VulkanError { try (MemoryStack stack = MemoryStack.stackPush()) { this.vkPhysicalDevice = vkPhysicalDevice; @@ -34,7 +34,8 @@ public class PhysicalDevice { vkCheck(vkEnumerateDeviceExtensionProperties(vkPhysicalDevice, (String) null, intBuffer, null), "Failed to get number of device extension properties"); vkDeviceExtensions = VkExtensionProperties.calloc(intBuffer.get(0)); - vkCheck(vkEnumerateDeviceExtensionProperties(vkPhysicalDevice, (String) null, intBuffer, vkDeviceExtensions), + vkCheck(vkEnumerateDeviceExtensionProperties(vkPhysicalDevice, (String) null, intBuffer, + vkDeviceExtensions), "Failed to get extension properties"); // Get Queue family properties @@ -51,7 +52,8 @@ public class PhysicalDevice { } } - public static PhysicalDevice createPhysicalDevice(Instance instance, Optional preferredDeviceName) { + public static PhysicalDevice createPhysicalDevice(Instance instance, Optional preferredDeviceName) + throws VulkanError { Logger.debug("Selecting physical devices"); PhysicalDevice selectedPhysicalDevice = null; try (MemoryStack stack = MemoryStack.stackPush()) { @@ -65,7 +67,8 @@ public class PhysicalDevice { // Populate available devices List devices = new ArrayList<>(); for (int i = 0; i < numDevices; i++) { - VkPhysicalDevice vkPhysicalDevice = new VkPhysicalDevice(pPhysicalDevices.get(i), instance.getVkInstance()); + VkPhysicalDevice vkPhysicalDevice = new VkPhysicalDevice(pPhysicalDevices.get(i), + instance.getVkInstance()); PhysicalDevice physicalDevice = new PhysicalDevice(vkPhysicalDevice); String deviceName = physicalDevice.getDeviceName(); @@ -83,7 +86,8 @@ public class PhysicalDevice { } // No preferred device or it does not meet requirements, just pick the first one - selectedPhysicalDevice = selectedPhysicalDevice == null && !devices.isEmpty() ? devices.remove(0) : selectedPhysicalDevice; + selectedPhysicalDevice = selectedPhysicalDevice == null && !devices.isEmpty() ? devices.remove(0) + : selectedPhysicalDevice; // Clean up non-selected devices for (PhysicalDevice physicalDevice : devices) { @@ -99,7 +103,7 @@ public class PhysicalDevice { return selectedPhysicalDevice; } - protected static PointerBuffer getPhysicalDevices(Instance instance, MemoryStack stack) { + protected static PointerBuffer getPhysicalDevices(Instance instance, MemoryStack stack) throws VulkanError { PointerBuffer pPhysicalDevices; // Get number of physical devices IntBuffer intBuffer = stack.mallocInt(1); diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/Queue.java b/src/main/java/fr/mrdev023/vulkan_java/vk/Queue.java similarity index 97% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/Queue.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/Queue.java index 0b10561..3f61387 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/Queue.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/Queue.java @@ -1,4 +1,4 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/Surface.java b/src/main/java/fr/mrdev023/vulkan_java/vk/Surface.java similarity index 69% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/Surface.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/Surface.java index 0d85f28..05e5f68 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/Surface.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/Surface.java @@ -1,11 +1,12 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import org.lwjgl.glfw.GLFWVulkan; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.KHRSurface; -import org.lwjgl.vulkan.VK10; import org.tinylog.Logger; +import static fr.mrdev023.vulkan_java.vk.VulkanError.vkCheck; + import java.nio.LongBuffer; public class Surface { @@ -13,25 +14,26 @@ public class Surface { private final PhysicalDevice physicalDevice; private final long vkSurface; - public Surface(PhysicalDevice physicalDevice, long windowHandle) { - Logger.debug("Creating Vulkan surface"); + public Surface(PhysicalDevice physicalDevice, long windowHandle) throws VulkanError { this.physicalDevice = physicalDevice; + try (MemoryStack stack = MemoryStack.stackPush()) { LongBuffer pSurface = stack.mallocLong(1); - var result = GLFWVulkan.glfwCreateWindowSurface(this.physicalDevice.getVkPhysicalDevice().getInstance(), windowHandle, - null, pSurface); - if (result != VK10.VK_SUCCESS) { - throw new RuntimeException("Failed to create Vulkan surface"); - } + var result = GLFWVulkan.glfwCreateWindowSurface(this.physicalDevice.getVkPhysicalDevice().getInstance(), + windowHandle, + null, pSurface); + vkCheck(result, "Failed to create Vulkan Surface"); vkSurface = pSurface.get(0); } + + Logger.debug("Vulkan surface created"); } public void destroy() { - Logger.debug("Destroying Vulkan surface"); KHRSurface.vkDestroySurfaceKHR(physicalDevice.getVkPhysicalDevice().getInstance(), vkSurface, null); + Logger.debug("Vulkan surface destroyed"); } public long getVkSurface() { diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/Vulkan.java b/src/main/java/fr/mrdev023/vulkan_java/vk/Vulkan.java similarity index 92% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/Vulkan.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/Vulkan.java index 20170b1..b5a04ad 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/Vulkan.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/Vulkan.java @@ -1,4 +1,4 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import fr.mrdev023.vulkan_java.window.Display; @@ -14,7 +14,7 @@ public class Vulkan { private static Surface surface; private static Queue.GraphicsQueue graphicsQueue; - public static void init() { + public static void init() throws VulkanError { if (!glfwVulkanSupported()) { throw new IllegalStateException("Cannot find a compatible Vulkan installable client driver (ICD)"); } diff --git a/src/main/java/fr/mrdev023/vulkan_java/vk/VulkanError.java b/src/main/java/fr/mrdev023/vulkan_java/vk/VulkanError.java new file mode 100644 index 0000000..247226c --- /dev/null +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/VulkanError.java @@ -0,0 +1,39 @@ +package fr.mrdev023.vulkan_java.vk; + +import org.lwjgl.vulkan.VK10; + +public class VulkanError extends Exception { + private VulkanError(int vulkanCode, String message) { + super(String.format("Vulkan error (Code: %s, Message: %s)", parseVulkanCode(vulkanCode), message)); + } + + public static void vkCheck(int result, String message) throws VulkanError { + if (result != VK10.VK_SUCCESS) { + throw new VulkanError(result, message); + } + } + + private static String parseVulkanCode(int code) { + return switch (code) { + case VK10.VK_NOT_READY -> "VK_NOT_READY"; + case VK10.VK_TIMEOUT -> "VK_TIMEOUT"; + case VK10.VK_EVENT_SET -> "VK_EVENT_SET"; + case VK10.VK_EVENT_RESET -> "VK_EVENT_RESET"; + case VK10.VK_INCOMPLETE -> "VK_INCOMPLETE"; + case VK10.VK_ERROR_OUT_OF_HOST_MEMORY -> "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK10.VK_ERROR_OUT_OF_DEVICE_MEMORY -> "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK10.VK_ERROR_INITIALIZATION_FAILED -> "VK_ERROR_INITIALIZATION_FAILED"; + case VK10.VK_ERROR_DEVICE_LOST -> "VK_ERROR_DEVICE_LOST"; + case VK10.VK_ERROR_MEMORY_MAP_FAILED -> "VK_ERROR_MEMORY_MAP_FAILED"; + case VK10.VK_ERROR_LAYER_NOT_PRESENT -> "VK_ERROR_LAYER_NOT_PRESENT"; + case VK10.VK_ERROR_EXTENSION_NOT_PRESENT -> "VK_ERROR_EXTENSION_NOT_PRESENT"; + case VK10.VK_ERROR_FEATURE_NOT_PRESENT -> "VK_ERROR_FEATURE_NOT_PRESENT"; + case VK10.VK_ERROR_INCOMPATIBLE_DRIVER -> "VK_ERROR_INCOMPATIBLE_DRIVER"; + case VK10.VK_ERROR_TOO_MANY_OBJECTS -> "VK_ERROR_TOO_MANY_OBJECTS"; + case VK10.VK_ERROR_FORMAT_NOT_SUPPORTED -> "VK_ERROR_FORMAT_NOT_SUPPORTED"; + case VK10.VK_ERROR_FRAGMENTED_POOL -> "VK_ERROR_FRAGMENTED_POOL"; + case VK10.VK_ERROR_UNKNOWN -> "VK_ERROR_UNKNOWN"; + default -> String.format("UNKNOWN(%s)", code); + }; + } +} diff --git a/src/main/java/fr/mrdev023/vulkan_java/renderer/VulkanUtils.java b/src/main/java/fr/mrdev023/vulkan_java/vk/VulkanUtils.java similarity index 60% rename from src/main/java/fr/mrdev023/vulkan_java/renderer/VulkanUtils.java rename to src/main/java/fr/mrdev023/vulkan_java/vk/VulkanUtils.java index 9845121..95b2c6b 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/renderer/VulkanUtils.java +++ b/src/main/java/fr/mrdev023/vulkan_java/vk/VulkanUtils.java @@ -1,15 +1,9 @@ -package fr.mrdev023.vulkan_java.renderer; +package fr.mrdev023.vulkan_java.vk; import java.util.Locale; -import static org.lwjgl.vulkan.VK11.VK_SUCCESS; - public class VulkanUtils { - private VulkanUtils() { - // Utility class - } - public static OSType getOS() { OSType result; String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); @@ -26,11 +20,7 @@ public class VulkanUtils { return result; } - public static void vkCheck(int err, String errMsg) { - if (err != VK_SUCCESS) { - throw new RuntimeException(errMsg + ": " + err); - } + public enum OSType { + WINDOWS, MACOS, LINUX, OTHER } - - public enum OSType {WINDOWS, MACOS, LINUX, OTHER} } diff --git a/src/main/java/fr/mrdev023/vulkan_java/window/Display.java b/src/main/java/fr/mrdev023/vulkan_java/window/Display.java index 81434c8..c1fe9d6 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/window/Display.java +++ b/src/main/java/fr/mrdev023/vulkan_java/window/Display.java @@ -1,6 +1,5 @@ package fr.mrdev023.vulkan_java.window; -import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.system.MemoryUtil.*; @@ -22,13 +21,13 @@ public class Display { TITLE = title; displayMode = new DisplayMode(width, height); - + // Configure GLFW for Vulkan glfwDefaultWindowHints(); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // Tell GLFW not to create an OpenGL context + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // Tell GLFW not to create an OpenGL context glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - + // Create the window window = glfwCreateWindow(displayMode.getWidth(), displayMode.getHeight(), TITLE, NULL, NULL); if (window == NULL) @@ -47,8 +46,10 @@ public class Display { } public static void setVSync(boolean a) { - if (a) glfwSwapInterval(1); - else glfwSwapInterval(0); + if (a) + glfwSwapInterval(1); + else + glfwSwapInterval(0); } public static void setSample(int sample) { @@ -56,8 +57,10 @@ public class Display { } public static void setResizable(boolean a) { - if (a) glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - else glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + if (a) + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + else + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); } public static void setTitle(String title) { @@ -76,7 +79,8 @@ public class Display { int width = w.get(0); int height = h.get(0); - if (Display.getDisplayMode().getWidth() != width || Display.getDisplayMode().getHeight() != height || hasResized) { + if (Display.getDisplayMode().getWidth() != width || Display.getDisplayMode().getHeight() != height + || hasResized) { setDisplayMode(new DisplayMode(width, height)); hasResized = false; return true; @@ -94,9 +98,11 @@ public class Display { } for (int i = 0; i < monitors.capacity(); i++) { m = glfwGetVideoMode(monitors.get(i)); - if (m == null) continue; + if (m == null) + continue; - System.out.println(glfwGetMonitorName(monitors.get(i)) + "(" + i + ") : " + m.width() + "x" + m.height() + ":" + m.refreshRate() + "Hz"); + System.out.println(glfwGetMonitorName(monitors.get(i)) + "(" + i + ") : " + m.width() + "x" + m.height() + + ":" + m.refreshRate() + "Hz"); } } @@ -118,7 +124,8 @@ public class Display { } public static void setDisplayMode(DisplayMode displayMode) { - if (Display.displayMode == null || displayMode == null) return; + if (Display.displayMode == null || displayMode == null) + return; Display.displayMode.setDisplayMode(displayMode); hasResized = true; } @@ -132,5 +139,4 @@ public class Display { return window; } - } \ No newline at end of file diff --git a/src/main/java/fr/mrdev023/vulkan_java/window/Input.java b/src/main/java/fr/mrdev023/vulkan_java/window/Input.java index 8355a32..e9751db 100644 --- a/src/main/java/fr/mrdev023/vulkan_java/window/Input.java +++ b/src/main/java/fr/mrdev023/vulkan_java/window/Input.java @@ -65,7 +65,8 @@ public class Input { int i = set.getKey(); int st = set.getValue(); if (i > -1 && i < NBRE_KEY) { - if (glfwGetKey(Display.getWindow(), i) == 0 && st == NONE) continue; + if (glfwGetKey(Display.getWindow(), i) == 0 && st == NONE) + continue; if (glfwGetKey(Display.getWindow(), i) == 1 && st == NONE) { state.replace(i, PRESSED); } else if (glfwGetKey(Display.getWindow(), i) == 1 && st == PRESSED) { @@ -76,12 +77,14 @@ public class Input { state.replace(i, NONE); } } else if (i >= MOUSE_OFFSET && i < MOUSE_OFFSET + NBRE_BUTTON) { - if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 0 && st == NONE) continue; + if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 0 && st == NONE) + continue; if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 1 && st == NONE) { state.replace(i, PRESSED); } else if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 1 && st == PRESSED) { state.replace(i, REPEATED); - } else if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 0 && (st == PRESSED || st == REPEATED)) { + } else if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 0 + && (st == PRESSED || st == REPEATED)) { state.replace(i, RELEASED); } else if (glfwGetMouseButton(Display.getWindow(), i - MOUSE_OFFSET) == 0 && st == RELEASED) { state.replace(i, NONE); diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties new file mode 100644 index 0000000..c462cb0 --- /dev/null +++ b/src/main/resources/tinylog.properties @@ -0,0 +1,2 @@ +writer = console +writer.format = {level}: {class}: {message}