-
Notifications
You must be signed in to change notification settings - Fork 28
/
Ch20IndexBuffer.diff
425 lines (352 loc) · 20.3 KB
/
Ch20IndexBuffer.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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
diff --git "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch19StagingBufferTransferQueue.java" "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch20IndexBuffer.java"
index 589b3bc..c6d6636 100644
--- "a/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch19StagingBufferTransferQueue.java"
+++ "b/G:\\Java-Dev\\Vulkan-Tutorial-Java\\src\\main\\java\\javavulkantutorial\\Ch20IndexBuffer.java"
@@ -33,20 +33,7 @@ import static org.lwjgl.vulkan.KHRSurface.*;
import static org.lwjgl.vulkan.KHRSwapchain.*;
import static org.lwjgl.vulkan.VK10.*;
-/**
- * This is an alternative version of the Staging Buffer Chapter, where I use a different queue family for transfer operations.
- *
- * As suggested in the tutorial, I will make the following modifications:
- *
- * - Modify QueueFamilyIndices and findQueueFamilies to explicitly look for a queue family with the VK_QUEUE_TRANSFER bit, but not the VK_QUEUE_GRAPHICS_BIT.
- * - Modify createLogicalDevice to request a handle to the transfer queue
- * - Create a second command pool for command buffers that are submitted on the transfer queue family
- * - Change the sharingMode of resources to be VK_SHARING_MODE_CONCURRENT and specify both the graphics and transfer queue families
- * - Submit any transfer commands like vkCmdCopyBuffer to the transfer queue instead of the graphics queue
- *
- *
- * */
-public class Ch19StagingBufferTransferQueue {
+public class Ch20IndexBuffer {
private static class HelloTriangleApplication {
@@ -72,7 +59,7 @@ public class Ch19StagingBufferTransferQueue {
}
private static final Set<String> DEVICE_EXTENSIONS = Stream.of(VK_KHR_SWAPCHAIN_EXTENSION_NAME)
- .collect(toSet());
+ .collect(toSet());
@@ -86,7 +73,7 @@ public class Ch19StagingBufferTransferQueue {
}
private static int createDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT createInfo,
- VkAllocationCallbacks allocationCallbacks, LongBuffer pDebugMessenger) {
+ VkAllocationCallbacks allocationCallbacks, LongBuffer pDebugMessenger) {
if(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT") != NULL) {
return vkCreateDebugUtilsMessengerEXT(instance, createInfo, allocationCallbacks, pDebugMessenger);
@@ -108,18 +95,17 @@ public class Ch19StagingBufferTransferQueue {
// We use Integer to use null as the empty value
private Integer graphicsFamily;
private Integer presentFamily;
- private Integer transferFamily;
private boolean isComplete() {
- return graphicsFamily != null && presentFamily != null && transferFamily != null;
+ return graphicsFamily != null && presentFamily != null;
}
public int[] unique() {
- return IntStream.of(graphicsFamily, presentFamily, transferFamily).distinct().toArray();
+ return IntStream.of(graphicsFamily, presentFamily).distinct().toArray();
}
public int[] array() {
- return new int[] {graphicsFamily, presentFamily, transferFamily};
+ return new int[] {graphicsFamily, presentFamily};
}
}
@@ -148,7 +134,7 @@ public class Ch19StagingBufferTransferQueue {
private static VkVertexInputBindingDescription.Buffer getBindingDescription(MemoryStack stack) {
VkVertexInputBindingDescription.Buffer bindingDescription =
- VkVertexInputBindingDescription.calloc(1, stack);
+ VkVertexInputBindingDescription.calloc(1, stack);
bindingDescription.binding(0);
bindingDescription.stride(Vertex.SIZEOF);
@@ -160,7 +146,7 @@ public class Ch19StagingBufferTransferQueue {
private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions(MemoryStack stack) {
VkVertexInputAttributeDescription.Buffer attributeDescriptions =
- VkVertexInputAttributeDescription.calloc(2);
+ VkVertexInputAttributeDescription.calloc(2);
// Position
VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(0);
@@ -182,9 +168,14 @@ public class Ch19StagingBufferTransferQueue {
}
private static final Vertex[] VERTICES = {
- new Vertex(new Vector2f(0.0f, -0.5f), new Vector3f(1.0f, 0.0f, 0.0f)),
- new Vertex(new Vector2f(0.5f, 0.5f), new Vector3f(0.0f, 1.0f, 0.0f)),
- new Vertex(new Vector2f(-0.5f, 0.5f), new Vector3f(0.0f, 0.0f, 1.0f))
+ new Vertex(new Vector2f(-0.5f, -0.5f), new Vector3f(1.0f, 0.0f, 0.0f)),
+ new Vertex(new Vector2f(0.5f, -0.5f), new Vector3f(0.0f, 1.0f, 0.0f)),
+ new Vertex(new Vector2f(0.5f, 0.5f), new Vector3f(0.0f, 0.0f, 1.0f)),
+ new Vertex(new Vector2f(-0.5f, 0.5f), new Vector3f(1.0f, 1.0f, 1.0f))
+ };
+
+ private static final /*uint16_t*/ short[] INDICES = {
+ 0, 1, 2, 2, 3, 0
};
// ======= FIELDS ======= //
@@ -200,7 +191,6 @@ public class Ch19StagingBufferTransferQueue {
private VkQueue graphicsQueue;
private VkQueue presentQueue;
- private VkQueue transferQueue;
private long swapChain;
private List<Long> swapChainImages;
@@ -214,13 +204,14 @@ public class Ch19StagingBufferTransferQueue {
private long graphicsPipeline;
private long commandPool;
- private long transferCommandPool;
private long vertexBuffer;
private long vertexBufferMemory;
+ private long indexBuffer;
+ private long indexBufferMemory;
+
private List<VkCommandBuffer> commandBuffers;
- private VkCommandBuffer transferCommandBuffer;
private List<Frame> inFlightFrames;
private Map<Integer, Frame> imagesInFlight;
@@ -277,6 +268,7 @@ public class Ch19StagingBufferTransferQueue {
createLogicalDevice();
createCommandPool();
createVertexBuffer();
+ createIndexBuffer();
createSwapChainObjects();
createSyncObjects();
}
@@ -313,8 +305,8 @@ public class Ch19StagingBufferTransferQueue {
cleanupSwapChain();
- vkFreeCommandBuffers(device, transferCommandPool, stackGet().pointers(transferCommandBuffer));
- vkDestroyCommandPool(device, transferCommandPool, null);
+ vkDestroyBuffer(device, indexBuffer, null);
+ vkFreeMemory(device, indexBufferMemory, null);
vkDestroyBuffer(device, vertexBuffer, null);
vkFreeMemory(device, vertexBufferMemory, null);
@@ -540,9 +532,6 @@ public class Ch19StagingBufferTransferQueue {
vkGetDeviceQueue(device, indices.presentFamily, 0, pQueue);
presentQueue = new VkQueue(pQueue.get(0), device);
-
- vkGetDeviceQueue(device, indices.transferFamily, 0, pQueue);
- transferQueue = new VkQueue(pQueue.get(0), device);
}
}
@@ -889,44 +878,57 @@ public class Ch19StagingBufferTransferQueue {
if (vkCreateCommandPool(device, poolInfo, null, pCommandPool) != VK_SUCCESS) {
throw new RuntimeException("Failed to create command pool");
}
+
commandPool = pCommandPool.get(0);
+ }
+ }
- // ===> Create the transfer command pool <===
+ private void createVertexBuffer() {
- poolInfo.queueFamilyIndex(queueFamilyIndices.transferFamily);
- // Tell Vulkan that the buffers of this pool will be constantly rerecorded
- poolInfo.flags(VK_COMMAND_POOL_CREATE_TRANSIENT_BIT);
+ try(MemoryStack stack = stackPush()) {
- if (vkCreateCommandPool(device, poolInfo, null, pCommandPool) != VK_SUCCESS) {
- throw new RuntimeException("Failed to create command pool");
- }
- transferCommandPool = pCommandPool.get(0);
+ long bufferSize = Vertex.SIZEOF * VERTICES.length;
- allocateTransferCommandBuffer();
- }
- }
+ LongBuffer pBuffer = stack.mallocLong(1);
+ LongBuffer pBufferMemory = stack.mallocLong(1);
+ createBuffer(bufferSize,
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+ pBuffer,
+ pBufferMemory);
- private void allocateTransferCommandBuffer() {
+ long stagingBuffer = pBuffer.get(0);
+ long stagingBufferMemory = pBufferMemory.get(0);
- try(MemoryStack stack = stackPush()) {
+ PointerBuffer data = stack.mallocPointer(1);
- VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack);
- allocInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO);
- allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
- allocInfo.commandPool(transferCommandPool);
- allocInfo.commandBufferCount(1);
+ vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, data);
+ {
+ memcpy(data.getByteBuffer(0, (int) bufferSize), VERTICES);
+ }
+ vkUnmapMemory(device, stagingBufferMemory);
- PointerBuffer pCommandBuffer = stack.mallocPointer(1);
- vkAllocateCommandBuffers(device, allocInfo, pCommandBuffer);
- transferCommandBuffer = new VkCommandBuffer(pCommandBuffer.get(0), device);
+ createBuffer(bufferSize,
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+ VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+ pBuffer,
+ pBufferMemory);
+
+ vertexBuffer = pBuffer.get(0);
+ vertexBufferMemory = pBufferMemory.get(0);
+
+ copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
+
+ vkDestroyBuffer(device, stagingBuffer, null);
+ vkFreeMemory(device, stagingBufferMemory, null);
}
}
- private void createVertexBuffer() {
+ private void createIndexBuffer() {
try(MemoryStack stack = stackPush()) {
- long bufferSize = Vertex.SIZEOF * VERTICES.length;
+ long bufferSize = Short.BYTES * INDICES.length;
LongBuffer pBuffer = stack.mallocLong(1);
LongBuffer pBufferMemory = stack.mallocLong(1);
@@ -943,20 +945,20 @@ public class Ch19StagingBufferTransferQueue {
vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, data);
{
- memcpy(data.getByteBuffer(0, (int) bufferSize), VERTICES);
+ memcpy(data.getByteBuffer(0, (int) bufferSize), INDICES);
}
vkUnmapMemory(device, stagingBufferMemory);
createBuffer(bufferSize,
- VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
pBuffer,
pBufferMemory);
- vertexBuffer = pBuffer.get(0);
- vertexBufferMemory = pBufferMemory.get(0);
+ indexBuffer = pBuffer.get(0);
+ indexBufferMemory = pBufferMemory.get(0);
- copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
+ copyBuffer(stagingBuffer, indexBuffer, bufferSize);
vkDestroyBuffer(device, stagingBuffer, null);
vkFreeMemory(device, stagingBufferMemory, null);
@@ -971,10 +973,7 @@ public class Ch19StagingBufferTransferQueue {
bufferInfo.sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
bufferInfo.size(size);
bufferInfo.usage(usage);
- // Change the sharing mode to concurrent (it will be shared between graphics and transfer queues)
- QueueFamilyIndices queueFamilies = findQueueFamilies(physicalDevice);
- bufferInfo.pQueueFamilyIndices(stack.ints(queueFamilies.graphicsFamily, queueFamilies.transferFamily));
- bufferInfo.sharingMode(VK_SHARING_MODE_CONCURRENT);
+ bufferInfo.sharingMode(VK_SHARING_MODE_EXCLUSIVE);
if(vkCreateBuffer(device, bufferInfo, null, pBuffer) != VK_SUCCESS) {
throw new RuntimeException("Failed to create vertex buffer");
@@ -1000,28 +999,39 @@ public class Ch19StagingBufferTransferQueue {
try(MemoryStack stack = stackPush()) {
+ VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack);
+ allocInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO);
+ allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+ allocInfo.commandPool(commandPool);
+ allocInfo.commandBufferCount(1);
+
+ PointerBuffer pCommandBuffer = stack.mallocPointer(1);
+ vkAllocateCommandBuffers(device, allocInfo, pCommandBuffer);
+ VkCommandBuffer commandBuffer = new VkCommandBuffer(pCommandBuffer.get(0), device);
+
VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.calloc(stack);
beginInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
beginInfo.flags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
- // Transfer command buffer implicitly reset
- vkBeginCommandBuffer(transferCommandBuffer, beginInfo);
+ vkBeginCommandBuffer(commandBuffer, beginInfo);
{
VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack);
copyRegion.size(size);
- vkCmdCopyBuffer(transferCommandBuffer, srcBuffer, dstBuffer, copyRegion);
+ vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion);
}
- vkEndCommandBuffer(transferCommandBuffer);
+ vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack);
submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO);
- submitInfo.pCommandBuffers(stack.pointers(transferCommandBuffer));
+ submitInfo.pCommandBuffers(pCommandBuffer);
- if(vkQueueSubmit(transferQueue, submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
+ if(vkQueueSubmit(graphicsQueue, submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
throw new RuntimeException("Failed to submit copy command buffer");
}
- vkQueueWaitIdle(transferQueue);
+ vkQueueWaitIdle(graphicsQueue);
+
+ vkFreeCommandBuffers(device, commandPool, pCommandBuffer);
}
}
@@ -1036,6 +1046,15 @@ public class Ch19StagingBufferTransferQueue {
}
}
+ private void memcpy(ByteBuffer buffer, short[] indices) {
+
+ for(short index : indices) {
+ buffer.putShort(index);
+ }
+
+ buffer.rewind();
+ }
+
private int findMemoryType(MemoryStack stack, int typeFilter, int properties) {
VkPhysicalDeviceMemoryProperties memProperties = VkPhysicalDeviceMemoryProperties.malloc(stack);
@@ -1110,7 +1129,9 @@ public class Ch19StagingBufferTransferQueue {
LongBuffer offsets = stack.longs(0);
vkCmdBindVertexBuffers(commandBuffer, 0, vertexBuffers, offsets);
- vkCmdDraw(commandBuffer, VERTICES.length, 1, 0, 0);
+ vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16);
+
+ vkCmdDrawIndexed(commandBuffer, INDICES.length, 1, 0, 0, 0);
}
vkCmdEndRenderPass(commandBuffer);
@@ -1145,11 +1166,11 @@ public class Ch19StagingBufferTransferQueue {
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) {
+ || 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)));
}
@@ -1185,7 +1206,7 @@ public class Ch19StagingBufferTransferQueue {
imagesInFlight.put(imageIndex, thisFrame);
- VkSubmitInfo submitInfo = VkSubmitInfo.callocStack(stack);
+ VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack);
submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO);
submitInfo.waitSemaphoreCount(1);
@@ -1247,10 +1268,10 @@ public class Ch19StagingBufferTransferQueue {
private VkSurfaceFormatKHR chooseSwapSurfaceFormat(VkSurfaceFormatKHR.Buffer availableFormats) {
return availableFormats.stream()
- .filter(availableFormat -> availableFormat.format() == VK_FORMAT_B8G8R8_UNORM)
- .filter(availableFormat -> availableFormat.colorSpace() == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
- .findAny()
- .orElse(availableFormats.get(0));
+ .filter(availableFormat -> availableFormat.format() == VK_FORMAT_B8G8R8_UNORM)
+ .filter(availableFormat -> availableFormat.colorSpace() == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
+ .findAny()
+ .orElse(availableFormats.get(0));
}
private int chooseSwapPresentMode(IntBuffer availablePresentModes) {
@@ -1373,14 +1394,6 @@ public class Ch19StagingBufferTransferQueue {
if((queueFamilies.get(i).queueFlags() & VK_QUEUE_GRAPHICS_BIT) != 0) {
indices.graphicsFamily = i;
}
- else if((queueFamilies.get(i).queueFlags() & VK_QUEUE_TRANSFER_BIT) != 0) {
- indices.transferFamily = i;
- }
- // In case of having only 1 queueFamily, use the same index since VK_QUEUE_GRAPHICS_BIT also implicitly
- // covers VK_QUEUE_TRANSFER_BIT
- if(queueFamilies.capacity() == 1){
- indices.transferFamily = i;
- }
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, presentSupport);
@@ -1398,8 +1411,8 @@ public class Ch19StagingBufferTransferQueue {
PointerBuffer buffer = stack.mallocPointer(collection.size());
collection.stream()
- .map(stack::UTF8)
- .forEach(buffer::put);
+ .map(stack::UTF8)
+ .forEach(buffer::put);
return buffer.rewind();
}
@@ -1444,8 +1457,8 @@ public class Ch19StagingBufferTransferQueue {
vkEnumerateInstanceLayerProperties(layerCount, availableLayers);
Set<String> availableLayerNames = availableLayers.stream()
- .map(VkLayerProperties::layerNameString)
- .collect(toSet());
+ .map(VkLayerProperties::layerNameString)
+ .collect(toSet());
return availableLayerNames.containsAll(VALIDATION_LAYERS);
}