-
Notifications
You must be signed in to change notification settings - Fork 28
/
Ch03PhysicalDeviceSelection.diff
120 lines (108 loc) · 4.19 KB
/
Ch03PhysicalDeviceSelection.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
diff --git "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch02ValidationLayers.java" "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch03PhysicalDeviceSelection.java"
index 4bf9c62..a6e48df 100644
--- "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch02ValidationLayers.java"
+++ "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch03PhysicalDeviceSelection.java"
@@ -8,6 +8,7 @@ import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.HashSet;
import java.util.Set;
+import java.util.stream.IntStream;
import static java.util.stream.Collectors.toSet;
import static org.lwjgl.glfw.GLFW.*;
@@ -19,7 +20,7 @@ import static org.lwjgl.system.MemoryUtil.NULL;
import static org.lwjgl.vulkan.EXTDebugUtils.*;
import static org.lwjgl.vulkan.VK10.*;
-public class Ch02ValidationLayers {
+public class Ch03PhysicalDeviceSelection {
private static class HelloTriangleApplication {
@@ -66,11 +67,23 @@ public class Ch02ValidationLayers {
}
+ private class QueueFamilyIndices {
+
+ // We use Integer to use null as the empty value
+ private Integer graphicsFamily;
+
+ private boolean isComplete() {
+ return graphicsFamily != null;
+ }
+
+ }
+
// ======= FIELDS ======= //
private long window;
private VkInstance instance;
private long debugMessenger;
+ private VkPhysicalDevice physicalDevice;
// ======= METHODS ======= //
@@ -102,6 +115,7 @@ public class Ch02ValidationLayers {
private void initVulkan() {
createInstance();
setupDebugMessenger();
+ pickPhysicalDevice();
}
private void mainLoop() {
@@ -200,6 +214,66 @@ public class Ch02ValidationLayers {
}
}
+ private void pickPhysicalDevice() {
+
+ try(MemoryStack stack = stackPush()) {
+
+ IntBuffer deviceCount = stack.ints(0);
+
+ vkEnumeratePhysicalDevices(instance, deviceCount, null);
+
+ if(deviceCount.get(0) == 0) {
+ throw new RuntimeException("Failed to find GPUs with Vulkan support");
+ }
+
+ PointerBuffer ppPhysicalDevices = stack.mallocPointer(deviceCount.get(0));
+
+ vkEnumeratePhysicalDevices(instance, deviceCount, ppPhysicalDevices);
+
+ for(int i = 0;i < ppPhysicalDevices.capacity();i++) {
+
+ VkPhysicalDevice device = new VkPhysicalDevice(ppPhysicalDevices.get(i), instance);
+
+ if(isDeviceSuitable(device)) {
+ physicalDevice = device;
+ return;
+ }
+ }
+
+ throw new RuntimeException("Failed to find a suitable GPU");
+ }
+ }
+
+ private boolean isDeviceSuitable(VkPhysicalDevice device) {
+
+ QueueFamilyIndices indices = findQueueFamilies(device);
+
+ return indices.isComplete();
+ }
+
+ private QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
+
+ QueueFamilyIndices indices = new QueueFamilyIndices();
+
+ try(MemoryStack stack = stackPush()) {
+
+ IntBuffer queueFamilyCount = stack.ints(0);
+
+ vkGetPhysicalDeviceQueueFamilyProperties(device, queueFamilyCount, null);
+
+ VkQueueFamilyProperties.Buffer queueFamilies = VkQueueFamilyProperties.malloc(queueFamilyCount.get(0), stack);
+
+ vkGetPhysicalDeviceQueueFamilyProperties(device, queueFamilyCount, queueFamilies);
+
+ IntStream.range(0, queueFamilies.capacity())
+ .filter(index -> (queueFamilies.get(index).queueFlags() & VK_QUEUE_GRAPHICS_BIT) != 0)
+ .findFirst()
+ .ifPresent(index -> indices.graphicsFamily = index);
+
+ return indices;
+ }
+ }
+
private PointerBuffer validationLayersAsPointerBuffer(MemoryStack stack) {
PointerBuffer buffer = stack.mallocPointer(VALIDATION_LAYERS.size());