-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathCh15HelloTriangle.diff
209 lines (187 loc) · 9.06 KB
/
Ch15HelloTriangle.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
diff --git "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch14CommandBuffers.java" "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch15HelloTriangle.java"
index 1caa3ce..e6ca21a 100644
--- "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch14CommandBuffers.java"
+++ "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch15HelloTriangle.java"
@@ -22,21 +22,24 @@ import static org.lwjgl.glfw.GLFWVulkan.glfwGetRequiredInstanceExtensions;
import static org.lwjgl.system.Configuration.DEBUG;
import static org.lwjgl.system.MemoryStack.stackGet;
import static org.lwjgl.system.MemoryStack.stackPush;
-import static org.lwjgl.system.MemoryUtil.NULL;
+import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.vulkan.EXTDebugUtils.*;
import static org.lwjgl.vulkan.KHRSurface.*;
import static org.lwjgl.vulkan.KHRSwapchain.*;
import static org.lwjgl.vulkan.VK10.*;
-public class Ch14CommandBuffers {
+public class Ch15HelloTriangle {
private static class HelloTriangleApplication {
private static final int UINT32_MAX = 0xFFFFFFFF;
+ private static final long UINT64_MAX = 0xFFFFFFFFFFFFFFFFL;
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
+ private static final int MAX_FRAMES_IN_FLIGHT = 2;
+
private static final boolean ENABLE_VALIDATION_LAYERS = DEBUG.get(true);
private static final Set<String> VALIDATION_LAYERS;
@@ -137,6 +140,10 @@ public class Ch14CommandBuffers {
private long commandPool;
private List<VkCommandBuffer> commandBuffers;
+ private List<Frame> inFlightFrames;
+ private Map<Integer, Frame> imagesInFlight;
+ private int currentFrame;
+
// ======= METHODS ======= //
public void run() {
@@ -177,18 +184,30 @@ public class Ch14CommandBuffers {
createFramebuffers();
createCommandPool();
createCommandBuffers();
+ createSyncObjects();
}
private void mainLoop() {
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
+ drawFrame();
}
+ // Wait for the device to complete all operations before release resources
+ vkDeviceWaitIdle(device);
}
private void cleanup() {
+ inFlightFrames.forEach(frame -> {
+
+ vkDestroySemaphore(device, frame.renderFinishedSemaphore(), null);
+ vkDestroySemaphore(device, frame.imageAvailableSemaphore(), null);
+ vkDestroyFence(device, frame.fence(), null);
+ });
+ imagesInFlight.clear();
+
vkDestroyCommandPool(device, commandPool, null);
swapChainFramebuffers.forEach(framebuffer -> vkDestroyFramebuffer(device, framebuffer, null));
@@ -519,10 +538,19 @@ public class Ch14CommandBuffers {
subpass.colorAttachmentCount(1);
subpass.pColorAttachments(colorAttachmentRef);
+ VkSubpassDependency.Buffer dependency = VkSubpassDependency.calloc(1, stack);
+ dependency.srcSubpass(VK_SUBPASS_EXTERNAL);
+ dependency.dstSubpass(0);
+ dependency.srcStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ dependency.srcAccessMask(0);
+ dependency.dstStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ dependency.dstAccessMask(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
+
VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.calloc(stack);
renderPassInfo.sType(VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
renderPassInfo.pAttachments(colorAttachment);
renderPassInfo.pSubpasses(subpass);
+ renderPassInfo.pDependencies(dependency);
LongBuffer pRenderPass = stack.mallocLong(1);
@@ -742,7 +770,7 @@ public class Ch14CommandBuffers {
PointerBuffer pCommandBuffers = stack.mallocPointer(commandBuffersCount);
if(vkAllocateCommandBuffers(device, allocInfo, pCommandBuffers) != VK_SUCCESS) {
- throw new RuntimeException("Fialed to allocate command buffers");
+ throw new RuntimeException("Failed to allocate command buffers");
}
for(int i = 0;i < commandBuffersCount;i++) {
@@ -754,11 +782,14 @@ public class Ch14CommandBuffers {
VkRenderPassBeginInfo renderPassInfo = VkRenderPassBeginInfo.calloc(stack);
renderPassInfo.sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO);
+
renderPassInfo.renderPass(renderPass);
+
VkRect2D renderArea = VkRect2D.calloc(stack);
renderArea.offset(VkOffset2D.calloc(stack).set(0, 0));
renderArea.extent(swapChainExtent);
renderPassInfo.renderArea(renderArea);
+
VkClearValue.Buffer clearValues = VkClearValue.calloc(1, stack);
clearValues.color().float32(stack.floats(0.0f, 0.0f, 0.0f, 1.0f));
renderPassInfo.pClearValues(clearValues);
@@ -792,6 +823,91 @@ public class Ch14CommandBuffers {
}
}
+ private void createSyncObjects() {
+
+ inFlightFrames = new ArrayList<>(MAX_FRAMES_IN_FLIGHT);
+ imagesInFlight = new HashMap<>(swapChainImages.size());
+
+ try(MemoryStack stack = stackPush()) {
+
+ VkSemaphoreCreateInfo semaphoreInfo = VkSemaphoreCreateInfo.calloc(stack);
+ semaphoreInfo.sType(VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
+
+ VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.calloc(stack);
+ fenceInfo.sType(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
+ fenceInfo.flags(VK_FENCE_CREATE_SIGNALED_BIT);
+
+ LongBuffer pImageAvailableSemaphore = stack.mallocLong(1);
+ LongBuffer pRenderFinishedSemaphore = stack.mallocLong(1);
+ LongBuffer pFence = stack.mallocLong(1);
+
+ for(int i = 0;i < MAX_FRAMES_IN_FLIGHT;i++) {
+
+ if(vkCreateSemaphore(device, semaphoreInfo, null, pImageAvailableSemaphore) != VK_SUCCESS
+ || vkCreateSemaphore(device, semaphoreInfo, null, pRenderFinishedSemaphore) != VK_SUCCESS
+ || vkCreateFence(device, fenceInfo, null, pFence) != VK_SUCCESS) {
+
+ throw new RuntimeException("Failed to create synchronization objects for the frame " + i);
+ }
+
+ inFlightFrames.add(new Frame(pImageAvailableSemaphore.get(0), pRenderFinishedSemaphore.get(0), pFence.get(0)));
+ }
+
+ }
+ }
+
+ private void drawFrame() {
+
+ try(MemoryStack stack = stackPush()) {
+
+ Frame thisFrame = inFlightFrames.get(currentFrame);
+
+ vkWaitForFences(device, thisFrame.pFence(), true, UINT64_MAX);
+
+ IntBuffer pImageIndex = stack.mallocInt(1);
+
+ vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, thisFrame.imageAvailableSemaphore(), VK_NULL_HANDLE, pImageIndex);
+ final int imageIndex = pImageIndex.get(0);
+
+ if(imagesInFlight.containsKey(imageIndex)) {
+ vkWaitForFences(device, imagesInFlight.get(imageIndex).fence(), true, UINT64_MAX);
+ }
+
+ imagesInFlight.put(imageIndex, thisFrame);
+
+ VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack);
+ submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO);
+
+ submitInfo.waitSemaphoreCount(1);
+ submitInfo.pWaitSemaphores(thisFrame.pImageAvailableSemaphore());
+ submitInfo.pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT));
+
+ submitInfo.pSignalSemaphores(thisFrame.pRenderFinishedSemaphore());
+
+ submitInfo.pCommandBuffers(stack.pointers(commandBuffers.get(imageIndex)));
+
+ vkResetFences(device, thisFrame.pFence());
+
+ if(vkQueueSubmit(graphicsQueue, submitInfo, thisFrame.fence()) != VK_SUCCESS) {
+ throw new RuntimeException("Failed to submit draw command buffer");
+ }
+
+ VkPresentInfoKHR presentInfo = VkPresentInfoKHR.calloc(stack);
+ presentInfo.sType(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR);
+
+ presentInfo.pWaitSemaphores(thisFrame.pRenderFinishedSemaphore());
+
+ presentInfo.swapchainCount(1);
+ presentInfo.pSwapchains(stack.longs(swapChain));
+
+ presentInfo.pImageIndices(pImageIndex);
+
+ vkQueuePresentKHR(presentQueue, presentInfo);
+
+ currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
+ }
+ }
+
private long createShaderModule(ByteBuffer spirvCode) {
try(MemoryStack stack = stackPush()) {