diff --git a/.gradle/8.14/checksums/checksums.lock b/.gradle/8.14/checksums/checksums.lock index a7ac98c..73e7ccf 100644 Binary files a/.gradle/8.14/checksums/checksums.lock and b/.gradle/8.14/checksums/checksums.lock differ diff --git a/.gradle/8.14/checksums/md5-checksums.bin b/.gradle/8.14/checksums/md5-checksums.bin index 4413880..652abe2 100644 Binary files a/.gradle/8.14/checksums/md5-checksums.bin and b/.gradle/8.14/checksums/md5-checksums.bin differ diff --git a/.gradle/8.14/checksums/sha1-checksums.bin b/.gradle/8.14/checksums/sha1-checksums.bin index 9bbbbc2..22ce6d3 100644 Binary files a/.gradle/8.14/checksums/sha1-checksums.bin and b/.gradle/8.14/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.14/executionHistory/executionHistory.bin b/.gradle/8.14/executionHistory/executionHistory.bin index 3ebe0dc..357bca2 100644 Binary files a/.gradle/8.14/executionHistory/executionHistory.bin and b/.gradle/8.14/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.14/executionHistory/executionHistory.lock b/.gradle/8.14/executionHistory/executionHistory.lock index 1c8ed34..eddb209 100644 Binary files a/.gradle/8.14/executionHistory/executionHistory.lock and b/.gradle/8.14/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.14/fileHashes/fileHashes.bin b/.gradle/8.14/fileHashes/fileHashes.bin index 292b8fc..7bbd37c 100644 Binary files a/.gradle/8.14/fileHashes/fileHashes.bin and b/.gradle/8.14/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.14/fileHashes/fileHashes.lock b/.gradle/8.14/fileHashes/fileHashes.lock index 465698c..21d2c99 100644 Binary files a/.gradle/8.14/fileHashes/fileHashes.lock and b/.gradle/8.14/fileHashes/fileHashes.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 29369b4..e53ec68 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index a7b69ad..1c814ed 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 94b4ced..28b7f94 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index ce61492..f19c87e 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanInstance.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanInstance.java index ec167d6..e84ea28 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanInstance.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanInstance.java @@ -1,18 +1,111 @@ package net.halbear.Terrain4J.EngineCore.Display; +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; +import org.lwjgl.PointerBuffer; +import org.lwjgl.glfw.GLFWVulkan; import org.lwjgl.system.MemoryStack; -import org.lwjgl.vulkan.VK; +import org.lwjgl.vulkan.EXTDebugUtils; import org.lwjgl.vulkan.VkApplicationInfo; +import org.lwjgl.vulkan.VkExtensionProperties; +import org.lwjgl.vulkan.VkLayerProperties; import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import static org.lwjgl.vulkan.VK10.vkEnumerateInstanceExtensionProperties; +import static org.lwjgl.vulkan.VK10.vkEnumerateInstanceLayerProperties; import static org.lwjgl.vulkan.VK14.VK_API_VERSION_1_4; + public class VulkanInstance { + private static final String VALIDATION_LAYER = "VK_LAYER_KHRONOS_validation"; + private static final String PORTABILITY_EXTENSION = "VK_KHR_portability_enumeration"; + public VulkanInstance(boolean validate){ - try (MemoryStack stack = MemoryStack.stackPush()) { - ByteBuffer appShortName = stack.UTF8("Terrain4J"); - var appInfo = VkApplicationInfo.calloc(stack).sType$Default().pApplicationName(appShortName).applicationVersion(1).pEngineName(appShortName).engineVersion(3).apiVersion(VK_API_VERSION_1_4); + try (MemoryStack MemStack = MemoryStack.stackPush()) { + ByteBuffer appShortName = MemStack.UTF8("Terrain4J"); + var appInfo = VkApplicationInfo.calloc(MemStack).sType$Default().pApplicationName(appShortName).applicationVersion(1).pEngineName(appShortName).engineVersion(3).apiVersion(VK_API_VERSION_1_4); + + //Vulkan operates in "Layers" and does minimal validation as it expects the developer to be competent, so we add these ourseves for better debugging + //refer to https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Validation_layers for an explanation + List ValidationLayers = getSupportedValidationLayers(); + int ValidationLayerCount = ValidationLayers.size(); + boolean SupportsValidation = validate; + if (validate && ValidationLayerCount == 0){ + SupportsValidation = false; + } + //once its done the validation layers, transform it into a pointer (null terminated string to be exact) + PointerBuffer RequiredLayers = null; + if (SupportsValidation){ + RequiredLayers = MemStack.mallocPointer(ValidationLayerCount); + for(int i = 0; i < ValidationLayerCount; i++){ + RequiredLayers.put(i, MemStack.ASCII(ValidationLayers.get(i))); + } + } + //enable MacOS Support because they use sum fuckin buuuullshiiiit + Set InstanceExtensions = getSupportedInstanceExtensions(); + boolean CrossPlatform = InstanceExtensions.contains(PORTABILITY_EXTENSION) && VulkanUtils.getOS() == VulkanUtils.OSType.MACOS; + + PointerBuffer GLFW_Extensions = GLFWVulkan.glfwGetRequiredInstanceExtensions(); + if (GLFW_Extensions == null){ + throw new RuntimeException("Failed to find the GLFW platform surface extensions for vulkan"); + } + + var ExtraExtensions = new ArrayList(); + if(SupportsValidation){ + ExtraExtensions.add(MemStack.UTF8(EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); + } + if(CrossPlatform){ + ExtraExtensions.add(MemStack.UTF8(PORTABILITY_EXTENSION)); + } + int ExtraExtensionsCount = ExtraExtensions.size(); + PointerBuffer RequiredExtensions = MemStack.mallocPointer(GLFW_Extensions.remaining() + ExtraExtensionsCount); + RequiredExtensions.put(GLFW_Extensions); + for(int i = 0; i < ExtraExtensionsCount; i++){ + RequiredExtensions.put(ExtraExtensions.get(i)); + } + RequiredExtensions.flip(); + } + } + private Set getSupportedInstanceExtensions(){ + Set InstanceExtensions = new HashSet<>(); + try(var MemStack = MemoryStack.stackPush()){ + IntBuffer ExtensionsBuffer = MemStack.callocInt(1); + vkEnumerateInstanceExtensionProperties((String)null,ExtensionsBuffer, null); + int ExtensionsCount = ExtensionsBuffer.get(0); + + var InstanceExtensionsProps = VkExtensionProperties.calloc(ExtensionsCount, MemStack); + vkEnumerateInstanceExtensionProperties((String)null,ExtensionsBuffer, InstanceExtensionsProps); + for(int i = 0; i < ExtensionsCount; i++){ + VkExtensionProperties Properties = InstanceExtensionsProps.get(i); + String ExtensionName = Properties.extensionNameString(); + InstanceExtensions.add(ExtensionName); + } + } + return InstanceExtensions; + } + private List getSupportedValidationLayers(){ + try(var MemStack = MemoryStack.stackPush()) { + IntBuffer LayersArray = MemStack.callocInt(1); + vkEnumerateInstanceLayerProperties(LayersArray, null); + int Layers = LayersArray.get(0); + var PropertiesBuffer = VkLayerProperties.calloc(Layers, MemStack); + vkEnumerateInstanceLayerProperties(LayersArray, PropertiesBuffer); + List SupportedLayers = new ArrayList<>(); + for (int i = 0; i < Layers; i++) { + VkLayerProperties properties = PropertiesBuffer.get(i); + String LayerName = properties.layerNameString(); + SupportedLayers.add(LayerName); + } + List LayersToUse = new ArrayList<>(); + if (SupportedLayers.contains(VALIDATION_LAYER)) { + LayersToUse.add(VALIDATION_LAYER); + } + return LayersToUse; } } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java new file mode 100644 index 0000000..865400a --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java @@ -0,0 +1,21 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Util; + +import java.util.Locale; + +public class VulkanUtils { + public enum OSType {WINDOWS, MACOS, LINUX, UNSUPPORTED} + public static OSType getOS() { + OSType result; + String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); + if ((os.contains("mac")) || (os.contains("darwin"))) { + result = OSType.MACOS; + } else if (os.contains("win")) { + result = OSType.WINDOWS; + } else if (os.contains("nux")) { + result = OSType.LINUX; + } else { + result = OSType.UNSUPPORTED; + } + return result; + } +} diff --git a/terrain4j.properties b/terrain4j.properties index 046ce4d..e7f6811 100644 --- a/terrain4j.properties +++ b/terrain4j.properties @@ -1,5 +1,5 @@ #created new properties file -#Mon Dec 15 10:15:30 GMT 2025 +#Thu Jan 15 13:32:39 GMT 2026 display_height=480 display_width=640 frame_accuracy=0