Vulkan Renderer Progress

This commit is contained in:
Harrison Corlett 2026-01-15 14:58:07 +00:00
parent 82db1f9321
commit e07da41f27
14 changed files with 119 additions and 5 deletions

Binary file not shown.

View file

@ -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<String> 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<String> 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<ByteBuffer>();
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<String> getSupportedInstanceExtensions(){
Set<String> 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<String> 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<String> SupportedLayers = new ArrayList<>();
for (int i = 0; i < Layers; i++) {
VkLayerProperties properties = PropertiesBuffer.get(i);
String LayerName = properties.layerNameString();
SupportedLayers.add(LayerName);
}
List<String> LayersToUse = new ArrayList<>();
if (SupportedLayers.contains(VALIDATION_LAYER)) {
LayersToUse.add(VALIDATION_LAYER);
}
return LayersToUse;
}
}
}

View file

@ -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;
}
}

View file

@ -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