Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/net/vulkanmod/mixin/window/WindowMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ private void redirect(int hint, int value) { }
private void vulkanHint(WindowEventHandler windowEventHandler, ScreenManager screenManager, DisplayData displayData, String string, String string2, CallbackInfo ci) {
GLFW.glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

// Enable 32bit P3 wide color gamut on macOS
if (Platform.isMacOS()) {
GLFW.glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE);
GLFW.glfwWindowHint(GLFW_RED_BITS, 10);
GLFW.glfwWindowHint(GLFW_GREEN_BITS, 10);
GLFW.glfwWindowHint(GLFW_BLUE_BITS, 10);
GLFW.glfwWindowHint(GLFW_ALPHA_BITS, 2);
}

//Fix Gnome Client-Side Decorators
boolean b = (Platform.isGnome() | Platform.isWeston() | Platform.isGeneric()) && Platform.isWayLand();
GLFW.glfwWindowHint(GLFW_DECORATED, (b ? GLFW_FALSE : GLFW_TRUE));
Expand Down
83 changes: 49 additions & 34 deletions src/main/java/net/vulkanmod/vulkan/Vulkan.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.vulkanmod.vulkan.util.VkResult;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import static org.lwjgl.vulkan.EXTSwapchainColorspace.VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME;
import org.lwjgl.util.vma.VmaAllocatorCreateInfo;
import org.lwjgl.util.vma.VmaVulkanFunctions;
import org.lwjgl.vulkan.*;
Expand Down Expand Up @@ -109,19 +110,11 @@ private static void destroyDebugUtilsMessengerEXT(VkInstance instance, long debu

}

public static VkDevice getVkDevice() {
return DeviceManager.vkDevice;
}

public static long getAllocator() {
return allocator;
}

public static long window;

private static VkInstance instance;
private static long debugMessenger;
private static long surface;
private static List<String> supportedInstanceExtensions;

private static long commandPool;
private static VkCommandBuffer immediateCmdBuffer;
Expand All @@ -131,6 +124,7 @@ public static long getAllocator() {

private static StagingBuffer[] stagingBuffers;

private static boolean colorSpaceExtSupport;
public static boolean use24BitsDepthFormat = true;
private static int DEFAULT_DEPTH_FORMAT = 0;

Expand Down Expand Up @@ -200,17 +194,16 @@ private static void freeStagingBuffers() {
}

private static void createInstance() {

if (ENABLE_VALIDATION_LAYERS && !checkValidationLayerSupport()) {
throw new RuntimeException("Validation requested but not supported");
}

try (MemoryStack stack = stackPush()) {
supportedInstanceExtensions = getAvailableInstanceExtension();
colorSpaceExtSupport = supportedInstanceExtensions.contains(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);

try (MemoryStack stack = stackPush()) {
// Use calloc to initialize the structs with 0s. Otherwise, the program can crash due to random values

VkApplicationInfo appInfo = VkApplicationInfo.calloc(stack);

appInfo.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO);
appInfo.pApplicationName(stack.UTF8Safe("VulkanMod"));
appInfo.applicationVersion(VK_MAKE_VERSION(1, 0, 0));
Expand All @@ -219,13 +212,11 @@ private static void createInstance() {
appInfo.apiVersion(VK_API_VERSION_1_2);

VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.calloc(stack);

createInfo.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
createInfo.pApplicationInfo(appInfo);
createInfo.ppEnabledExtensionNames(getRequiredInstanceExtensions());

if (ENABLE_VALIDATION_LAYERS) {

createInfo.ppEnabledLayerNames(asPointerBuffer(VALIDATION_LAYERS));

VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);
Expand All @@ -244,9 +235,7 @@ private static void createInstance() {
}

static boolean checkValidationLayerSupport() {

try (MemoryStack stack = stackPush()) {

IntBuffer layerCount = stack.ints(0);

vkEnumerateInstanceLayerProperties(layerCount, null);
Expand All @@ -273,13 +262,11 @@ private static void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreate
}

private static void setupDebugMessenger() {

if (!ENABLE_VALIDATION_LAYERS) {
return;
}

try (MemoryStack stack = stackPush()) {

VkDebugUtilsMessengerCreateInfoEXT createInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);

populateDebugMessengerCreateInfo(createInfo);
Expand Down Expand Up @@ -308,7 +295,6 @@ private static void createSurface(long handle) {
window = handle;

try (MemoryStack stack = stackPush()) {

LongBuffer pSurface = stack.longs(VK_NULL_HANDLE);

checkResult(glfwCreateWindowSurface(instance, window, null, pSurface),
Expand All @@ -320,7 +306,6 @@ private static void createSurface(long handle) {

private static void createVma() {
try (MemoryStack stack = stackPush()) {

VmaVulkanFunctions vulkanFunctions = VmaVulkanFunctions.calloc(stack);
vulkanFunctions.set(instance, DeviceManager.vkDevice);

Expand All @@ -341,9 +326,7 @@ private static void createVma() {
}

private static void createCommandPool() {

try (MemoryStack stack = stackPush()) {

Queue.QueueFamilyIndices queueFamilyIndices = getQueueFamilies();

VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.calloc(stack);
Expand All @@ -360,24 +343,44 @@ private static void createCommandPool() {
}
}

private static PointerBuffer getRequiredInstanceExtensions() {
private static List<String> getAvailableInstanceExtension() {
try (MemoryStack stack = MemoryStack.stackPush()) {
// Query first for extension count
IntBuffer extensionCount = stack.ints(0);
vkEnumerateInstanceExtensionProperties((String) null, extensionCount, null);

VkExtensionProperties.Buffer availableExtensions = VkExtensionProperties.malloc(extensionCount.get(0), stack);
vkEnumerateInstanceExtensionProperties((String) null, extensionCount, availableExtensions);

return availableExtensions.stream()
.map(VkExtensionProperties::extensionNameString)
.toList();
}
}

private static PointerBuffer getRequiredInstanceExtensions() {
PointerBuffer glfwExtensions = glfwGetRequiredInstanceExtensions();
MemoryStack stack = stackGet();

if (ENABLE_VALIDATION_LAYERS) {
List<String> requestedExtensions = new ArrayList<>();

MemoryStack stack = stackGet();
// Check for VK_EXT_SWAPCHAIN_COLOR_SPACE support
if (supportedInstanceExtensions.contains(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) {
requestedExtensions.add(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
}

PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + 1);
if (ENABLE_VALIDATION_LAYERS) {
requestedExtensions.add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}

extensions.put(glfwExtensions);
extensions.put(stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + requestedExtensions.size());
extensions.put(glfwExtensions);

// Rewind the buffer before returning it to reset its position back to 0
return extensions.rewind();
for (String extName : requestedExtensions) {
extensions.put(stack.UTF8(extName));
}

return glfwExtensions;
return extensions.rewind();
}

public static void checkResult(int result, String errorMessage) {
Expand All @@ -394,8 +397,12 @@ public static void setVsync(boolean b) {
}
}

public static int getDefaultDepthFormat() {
return DEFAULT_DEPTH_FORMAT;
public static VkDevice getVkDevice() {
return DeviceManager.vkDevice;
}

public static long getAllocator() {
return allocator;
}

public static long getSurface() {
Expand All @@ -413,5 +420,13 @@ public static StagingBuffer getStagingBuffer() {
public static Device getDevice() {
return DeviceManager.device;
}

public static boolean colorSpaceExtSupport() {
return colorSpaceExtSupport;
}

public static int getDefaultDepthFormat() {
return DEFAULT_DEPTH_FORMAT;
}
}

97 changes: 44 additions & 53 deletions src/main/java/net/vulkanmod/vulkan/device/Device.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package net.vulkanmod.vulkan.device;

import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.*;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;

import java.nio.IntBuffer;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static java.util.stream.Collectors.toSet;
import static org.lwjgl.glfw.GLFW.GLFW_PLATFORM_WIN32;
import static org.lwjgl.glfw.GLFW.glfwGetPlatform;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK11.vkEnumerateInstanceVersion;
import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2;
Expand All @@ -31,15 +27,13 @@ public class Device {
public final VkPhysicalDeviceFeatures2 availableFeatures;
public final VkPhysicalDeviceVulkan11Features availableFeatures11;

// public final VkPhysicalDeviceVulkan13Features availableFeatures13;
// public final boolean vulkan13Support;

private boolean drawIndirectSupported;
public final List<String> supportedExtensions;
public final boolean drawIndirectSupported;

public Device(VkPhysicalDevice device) {
this.physicalDevice = device;

properties = VkPhysicalDeviceProperties.malloc();
this.properties = VkPhysicalDeviceProperties.malloc();
vkGetPhysicalDeviceProperties(physicalDevice, properties);

this.vendorId = properties.vendorID();
Expand All @@ -55,18 +49,40 @@ public Device(VkPhysicalDevice device) {
this.availableFeatures11.sType$Default();
this.availableFeatures.pNext(this.availableFeatures11);

//Vulkan 1.3
// this.availableFeatures13 = VkPhysicalDeviceVulkan13Features.malloc();
// this.availableFeatures13.sType$Default();
// this.availableFeatures11.pNext(this.availableFeatures13.address());
//
// this.vulkan13Support = this.device.getCapabilities().apiVersion == VK_API_VERSION_1_3;

vkGetPhysicalDeviceFeatures2(this.physicalDevice, this.availableFeatures);

if (this.availableFeatures.features().multiDrawIndirect() && this.availableFeatures11.shaderDrawParameters())
this.drawIndirectSupported = true;
this.drawIndirectSupported = this.availableFeatures.features().multiDrawIndirect();

this.supportedExtensions = getAvailableExtension(device);
}

public List<String> getSupportedExtensions() {
return supportedExtensions;
}

public Set<String> getUnsupportedExtensions(Set<String> requiredExtensions) {
Set<String> unsupportedExtensions = new HashSet<>(requiredExtensions);
supportedExtensions.forEach(unsupportedExtensions::remove);

return unsupportedExtensions;
}

public boolean isDrawIndirectSupported() {
return drawIndirectSupported;
}

// Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances:
// (e.g. such as in case we encounter a vendor specific driver bug)
public boolean isAMD() {
return vendorId == 0x1022;
}

public boolean isNvidia() {
return vendorId == 0x10DE;
}

public boolean isIntel() {
return vendorId == 0x8086;
}

private static String decodeVendor(int i) {
Expand Down Expand Up @@ -108,7 +124,7 @@ private static String decodeNvidia(int v) {
return (v >>> 22 & 0x3FF) + "." + (v >>> 14 & 0xff) + "." + (v >>> 6 & 0xff) + "." + (v & 0xff);
}

static int getVkVer() {
private static int getVkVer() {
try (MemoryStack stack = MemoryStack.stackPush()) {
var a = stack.mallocInt(1);
vkEnumerateInstanceVersion(a);
Expand All @@ -120,43 +136,18 @@ static int getVkVer() {
}
}

public Set<String> getUnsupportedExtensions(Set<String> requiredExtensions) {
try (MemoryStack stack = stackPush()) {

private static List<String> getAvailableExtension(VkPhysicalDevice device) {
try (MemoryStack stack = MemoryStack.stackPush()) {
// Query first for extension count
IntBuffer extensionCount = stack.ints(0);

vkEnumerateDeviceExtensionProperties(physicalDevice, (String) null, extensionCount, null);
vkEnumerateDeviceExtensionProperties(device, (String) null, extensionCount, null);

VkExtensionProperties.Buffer availableExtensions = VkExtensionProperties.malloc(extensionCount.get(0), stack);
vkEnumerateDeviceExtensionProperties(device, (String) null, extensionCount, availableExtensions);

vkEnumerateDeviceExtensionProperties(physicalDevice, (String) null, extensionCount, availableExtensions);

Set<String> extensions = availableExtensions.stream()
.map(VkExtensionProperties::extensionNameString)
.collect(toSet());

Set<String> unsupportedExtensions = new HashSet<>(requiredExtensions);
unsupportedExtensions.removeAll(extensions);

return unsupportedExtensions;
return availableExtensions.stream()
.map(VkExtensionProperties::extensionNameString)
.toList();
}
}

public boolean isDrawIndirectSupported() {
return drawIndirectSupported;
}

// Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances:
// (e.g. such as in case we encounter a vendor specific driver bug)
public boolean isAMD() {
return vendorId == 0x1022;
}

public boolean isNvidia() {
return vendorId == 0x10DE;
}

public boolean isIntel() {
return vendorId == 0x8086;
}
}
Loading