Skip to content

Commit a479e87

Browse files
committed
Add check for VK_EXT_swapchain_colorspace extension support
- refactor init
1 parent f409c8b commit a479e87

4 files changed

Lines changed: 126 additions & 115 deletions

File tree

src/main/java/net/vulkanmod/vulkan/Vulkan.java

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,11 @@ private static void destroyDebugUtilsMessengerEXT(VkInstance instance, long debu
110110

111111
}
112112

113-
public static VkDevice getVkDevice() {
114-
return DeviceManager.vkDevice;
115-
}
116-
117-
public static long getAllocator() {
118-
return allocator;
119-
}
120-
121113
public static long window;
122-
123114
private static VkInstance instance;
124115
private static long debugMessenger;
125116
private static long surface;
117+
private static List<String> supportedInstanceExtensions;
126118

127119
private static long commandPool;
128120
private static VkCommandBuffer immediateCmdBuffer;
@@ -132,6 +124,7 @@ public static long getAllocator() {
132124

133125
private static StagingBuffer[] stagingBuffers;
134126

127+
private static boolean colorSpaceExtSupport;
135128
public static boolean use24BitsDepthFormat = true;
136129
private static int DEFAULT_DEPTH_FORMAT = 0;
137130

@@ -201,17 +194,16 @@ private static void freeStagingBuffers() {
201194
}
202195

203196
private static void createInstance() {
204-
205197
if (ENABLE_VALIDATION_LAYERS && !checkValidationLayerSupport()) {
206198
throw new RuntimeException("Validation requested but not supported");
207199
}
208200

209-
try (MemoryStack stack = stackPush()) {
201+
supportedInstanceExtensions = getAvailableInstanceExtension();
202+
colorSpaceExtSupport = supportedInstanceExtensions.contains(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
210203

204+
try (MemoryStack stack = stackPush()) {
211205
// Use calloc to initialize the structs with 0s. Otherwise, the program can crash due to random values
212-
213206
VkApplicationInfo appInfo = VkApplicationInfo.calloc(stack);
214-
215207
appInfo.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO);
216208
appInfo.pApplicationName(stack.UTF8Safe("VulkanMod"));
217209
appInfo.applicationVersion(VK_MAKE_VERSION(1, 0, 0));
@@ -220,13 +212,11 @@ private static void createInstance() {
220212
appInfo.apiVersion(VK_API_VERSION_1_2);
221213

222214
VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.calloc(stack);
223-
224215
createInfo.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
225216
createInfo.pApplicationInfo(appInfo);
226217
createInfo.ppEnabledExtensionNames(getRequiredInstanceExtensions());
227218

228219
if (ENABLE_VALIDATION_LAYERS) {
229-
230220
createInfo.ppEnabledLayerNames(asPointerBuffer(VALIDATION_LAYERS));
231221

232222
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);
@@ -245,9 +235,7 @@ private static void createInstance() {
245235
}
246236

247237
static boolean checkValidationLayerSupport() {
248-
249238
try (MemoryStack stack = stackPush()) {
250-
251239
IntBuffer layerCount = stack.ints(0);
252240

253241
vkEnumerateInstanceLayerProperties(layerCount, null);
@@ -274,13 +262,11 @@ private static void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreate
274262
}
275263

276264
private static void setupDebugMessenger() {
277-
278265
if (!ENABLE_VALIDATION_LAYERS) {
279266
return;
280267
}
281268

282269
try (MemoryStack stack = stackPush()) {
283-
284270
VkDebugUtilsMessengerCreateInfoEXT createInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);
285271

286272
populateDebugMessengerCreateInfo(createInfo);
@@ -309,7 +295,6 @@ private static void createSurface(long handle) {
309295
window = handle;
310296

311297
try (MemoryStack stack = stackPush()) {
312-
313298
LongBuffer pSurface = stack.longs(VK_NULL_HANDLE);
314299

315300
checkResult(glfwCreateWindowSurface(instance, window, null, pSurface),
@@ -321,7 +306,6 @@ private static void createSurface(long handle) {
321306

322307
private static void createVma() {
323308
try (MemoryStack stack = stackPush()) {
324-
325309
VmaVulkanFunctions vulkanFunctions = VmaVulkanFunctions.calloc(stack);
326310
vulkanFunctions.set(instance, DeviceManager.vkDevice);
327311

@@ -342,9 +326,7 @@ private static void createVma() {
342326
}
343327

344328
private static void createCommandPool() {
345-
346329
try (MemoryStack stack = stackPush()) {
347-
348330
Queue.QueueFamilyIndices queueFamilyIndices = getQueueFamilies();
349331

350332
VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.calloc(stack);
@@ -361,21 +343,43 @@ private static void createCommandPool() {
361343
}
362344
}
363345

346+
private static List<String> getAvailableInstanceExtension() {
347+
try (MemoryStack stack = MemoryStack.stackPush()) {
348+
// Query first for extension count
349+
IntBuffer extensionCount = stack.ints(0);
350+
vkEnumerateInstanceExtensionProperties((String) null, extensionCount, null);
351+
352+
VkExtensionProperties.Buffer availableExtensions = VkExtensionProperties.malloc(extensionCount.get(0), stack);
353+
vkEnumerateInstanceExtensionProperties((String) null, extensionCount, availableExtensions);
354+
355+
return availableExtensions.stream()
356+
.map(VkExtensionProperties::extensionNameString)
357+
.toList();
358+
}
359+
}
360+
364361
private static PointerBuffer getRequiredInstanceExtensions() {
365362
PointerBuffer glfwExtensions = glfwGetRequiredInstanceExtensions();
366363
MemoryStack stack = stackGet();
367364

365+
List<String> requestedExtensions = new ArrayList<>();
366+
367+
// Check for VK_EXT_SWAPCHAIN_COLOR_SPACE support
368+
if (supportedInstanceExtensions.contains(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) {
369+
requestedExtensions.add(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
370+
}
371+
368372
if (ENABLE_VALIDATION_LAYERS) {
369-
PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + 2);
370-
extensions.put(glfwExtensions);
371-
extensions.put(stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
372-
extensions.put(stack.UTF8(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME));
373-
return extensions.rewind();
373+
requestedExtensions.add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
374374
}
375375

376-
PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + 1);
376+
PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + requestedExtensions.size());
377377
extensions.put(glfwExtensions);
378-
extensions.put(stack.UTF8(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME));
378+
379+
for (String extName : requestedExtensions) {
380+
extensions.put(stack.UTF8(extName));
381+
}
382+
379383
return extensions.rewind();
380384
}
381385

@@ -393,8 +397,12 @@ public static void setVsync(boolean b) {
393397
}
394398
}
395399

396-
public static int getDefaultDepthFormat() {
397-
return DEFAULT_DEPTH_FORMAT;
400+
public static VkDevice getVkDevice() {
401+
return DeviceManager.vkDevice;
402+
}
403+
404+
public static long getAllocator() {
405+
return allocator;
398406
}
399407

400408
public static long getSurface() {
@@ -412,5 +420,13 @@ public static StagingBuffer getStagingBuffer() {
412420
public static Device getDevice() {
413421
return DeviceManager.device;
414422
}
423+
424+
public static boolean colorSpaceExtSupport() {
425+
return colorSpaceExtSupport;
426+
}
427+
428+
public static int getDefaultDepthFormat() {
429+
return DEFAULT_DEPTH_FORMAT;
430+
}
415431
}
416432

src/main/java/net/vulkanmod/vulkan/device/Device.java

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
package net.vulkanmod.vulkan.device;
22

3-
import org.lwjgl.PointerBuffer;
43
import org.lwjgl.system.MemoryStack;
54
import org.lwjgl.vulkan.*;
6-
import oshi.SystemInfo;
7-
import oshi.hardware.CentralProcessor;
85

96
import java.nio.IntBuffer;
107
import java.util.HashSet;
8+
import java.util.List;
119
import java.util.Set;
1210

13-
import static java.util.stream.Collectors.toSet;
1411
import static org.lwjgl.glfw.GLFW.GLFW_PLATFORM_WIN32;
1512
import static org.lwjgl.glfw.GLFW.glfwGetPlatform;
16-
import static org.lwjgl.system.MemoryStack.stackPush;
1713
import static org.lwjgl.vulkan.VK10.*;
1814
import static org.lwjgl.vulkan.VK11.vkEnumerateInstanceVersion;
1915
import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2;
@@ -31,15 +27,13 @@ public class Device {
3127
public final VkPhysicalDeviceFeatures2 availableFeatures;
3228
public final VkPhysicalDeviceVulkan11Features availableFeatures11;
3329

34-
// public final VkPhysicalDeviceVulkan13Features availableFeatures13;
35-
// public final boolean vulkan13Support;
36-
37-
private boolean drawIndirectSupported;
30+
public final List<String> supportedExtensions;
31+
public final boolean drawIndirectSupported;
3832

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

42-
properties = VkPhysicalDeviceProperties.malloc();
36+
this.properties = VkPhysicalDeviceProperties.malloc();
4337
vkGetPhysicalDeviceProperties(physicalDevice, properties);
4438

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

58-
//Vulkan 1.3
59-
// this.availableFeatures13 = VkPhysicalDeviceVulkan13Features.malloc();
60-
// this.availableFeatures13.sType$Default();
61-
// this.availableFeatures11.pNext(this.availableFeatures13.address());
62-
//
63-
// this.vulkan13Support = this.device.getCapabilities().apiVersion == VK_API_VERSION_1_3;
64-
6552
vkGetPhysicalDeviceFeatures2(this.physicalDevice, this.availableFeatures);
6653

67-
if (this.availableFeatures.features().multiDrawIndirect() && this.availableFeatures11.shaderDrawParameters())
68-
this.drawIndirectSupported = true;
54+
this.drawIndirectSupported = this.availableFeatures.features().multiDrawIndirect();
55+
56+
this.supportedExtensions = getAvailableExtension(device);
57+
}
58+
59+
public List<String> getSupportedExtensions() {
60+
return supportedExtensions;
61+
}
62+
63+
public Set<String> getUnsupportedExtensions(Set<String> requiredExtensions) {
64+
Set<String> unsupportedExtensions = new HashSet<>(requiredExtensions);
65+
supportedExtensions.forEach(unsupportedExtensions::remove);
66+
67+
return unsupportedExtensions;
68+
}
69+
70+
public boolean isDrawIndirectSupported() {
71+
return drawIndirectSupported;
72+
}
73+
74+
// Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances:
75+
// (e.g. such as in case we encounter a vendor specific driver bug)
76+
public boolean isAMD() {
77+
return vendorId == 0x1022;
78+
}
6979

80+
public boolean isNvidia() {
81+
return vendorId == 0x10DE;
82+
}
83+
84+
public boolean isIntel() {
85+
return vendorId == 0x8086;
7086
}
7187

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

111-
static int getVkVer() {
127+
private static int getVkVer() {
112128
try (MemoryStack stack = MemoryStack.stackPush()) {
113129
var a = stack.mallocInt(1);
114130
vkEnumerateInstanceVersion(a);
@@ -120,43 +136,18 @@ static int getVkVer() {
120136
}
121137
}
122138

123-
public Set<String> getUnsupportedExtensions(Set<String> requiredExtensions) {
124-
try (MemoryStack stack = stackPush()) {
125-
139+
private static List<String> getAvailableExtension(VkPhysicalDevice device) {
140+
try (MemoryStack stack = MemoryStack.stackPush()) {
141+
// Query first for extension count
126142
IntBuffer extensionCount = stack.ints(0);
127-
128-
vkEnumerateDeviceExtensionProperties(physicalDevice, (String) null, extensionCount, null);
143+
vkEnumerateDeviceExtensionProperties(device, (String) null, extensionCount, null);
129144

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

132-
vkEnumerateDeviceExtensionProperties(physicalDevice, (String) null, extensionCount, availableExtensions);
133-
134-
Set<String> extensions = availableExtensions.stream()
135-
.map(VkExtensionProperties::extensionNameString)
136-
.collect(toSet());
137-
138-
Set<String> unsupportedExtensions = new HashSet<>(requiredExtensions);
139-
unsupportedExtensions.removeAll(extensions);
140-
141-
return unsupportedExtensions;
148+
return availableExtensions.stream()
149+
.map(VkExtensionProperties::extensionNameString)
150+
.toList();
142151
}
143152
}
144-
145-
public boolean isDrawIndirectSupported() {
146-
return drawIndirectSupported;
147-
}
148-
149-
// Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances:
150-
// (e.g. such as in case we encounter a vendor specific driver bug)
151-
public boolean isAMD() {
152-
return vendorId == 0x1022;
153-
}
154-
155-
public boolean isNvidia() {
156-
return vendorId == 0x10DE;
157-
}
158-
159-
public boolean isIntel() {
160-
return vendorId == 0x8086;
161-
}
162153
}

0 commit comments

Comments
 (0)