Skip to content

Commit ec197ef

Browse files
committed
Fix memory issue when instantiating device extension properties
1 parent ebe25ab commit ec197ef

File tree

28 files changed

+212
-164
lines changed

28 files changed

+212
-164
lines changed

bookcontents/chapter-02/chapter-02.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ We will see if [Project Panama](https://openjdk.java.net/projects/panama/) can f
5858
`malloc` is suggested for performance gains, but sometimes calloc is necessary.
5959
When using calloc, we do not need to initialize some information fields.*
6060

61+
> [!WARNING]
62+
> Keep in mind that you should not allocate large objects in the `MemoryStack`. You should use it for relative small short lived objects.
63+
> In case you need to allocate larger objects, either you should increase its default size, or use allocation methods that do not require a `MemoryStack` instance.
64+
> In this case, you need to either manually free the allocation or perform the allocation in a `try` `catch` block.
65+
6166
### Creating Vulkan Structures
6267

6368
Here you can see the basis of all the Vulkan calls.

bookcontents/chapter-03/chapter-03.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,14 @@ public class Device {
396396
}
397397
```
398398

399-
First we retrieve the supported device extensions by calling the `getDeviceExtensions` (we will see it later). If we are on MacOS and portability subset extension is supported, we need to enable it. Additionally, if you recall, when selecting the physical device we checked if it supported the KHR Swap chain extension, now it is the turn to explicitly say that we are going to use it. In order to define required extensions, we create a `PointerBuffer` which will hold a list of `null` terminated strings. The `getDeviceExtensions` method is similar to the one defined to get instance extensions. We just first call the `vkEnumerateDeviceExtensionProperties` to get the number of extensions,
400-
create a `VkExtensionProperties` buffer to hold all the values and call `vkEnumerateDeviceExtensionProperties` to populate it. After that we just transfer all t he data
401-
to a `Set` of `String`s:
399+
First we retrieve the supported device extensions by calling the `getDeviceExtensions` (we will see it later). If we are on MacOS and portability subset extension is supported, we need to enable it. Additionally, if you recall, when selecting the physical device we checked if it supported the KHR Swap chain extension, now it is the turn to explicitly say that we are going to use it. In order to define required extensions, we create a `PointerBuffer` which will hold a list of `null` terminated strings.
400+
The `getDeviceExtensions` method is similar to the one defined to get instance extensions. We just first call the `vkEnumerateDeviceExtensionProperties` to get the number
401+
of extensions, create a `VkExtensionProperties` buffer to hold all the values and call `vkEnumerateDeviceExtensionProperties` to populate it. After that we just transfer
402+
all the data to a `Set` of `String`s. You will notice that we do not use the `stack` to allocate device extensions. Depending on your local configuration, the
403+
number of extensions can be quite large, and the memory required to allocate all that information can exceed default stack size.
404+
To prevent incurring in an "Out of stack space" error, we will allocate `VkExtensionProperties` in a `try` `catch` block to automatically allocate and deallocate it
405+
without using LWJGL's stack.
406+
402407

403408
```java
404409
public class Device {
@@ -411,13 +416,15 @@ public class Device {
411416
int numExtensions = numExtensionsBuf.get(0);
412417
Logger.trace("Device supports [{}] extensions", numExtensions);
413418

414-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
415-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
416-
for (int i = 0; i < numExtensions; i++) {
417-
VkExtensionProperties props = propsBuff.get(i);
418-
String extensionName = props.extensionNameString();
419-
deviceExtensions.add(extensionName);
420-
Logger.trace("Supported device extension [{}]", extensionName);
419+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
420+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
421+
for (int i = 0; i < numExtensions; i++) {
422+
VkExtensionProperties props = propsBuff.get(i);
423+
String extensionName = props.extensionNameString();
424+
deviceExtensions.add(extensionName);
425+
Logger.trace("Supported device extension [{}]", extensionName);
426+
}
427+
421428
}
422429
}
423430
return deviceExtensions;

booksamples/appendix-01/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
115115
int numExtensions = numExtensionsBuf.get(0);
116116
Logger.trace("Device supports [{}] extensions", numExtensions);
117117

118-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
119-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
120-
for (int i = 0; i < numExtensions; i++) {
121-
VkExtensionProperties props = propsBuff.get(i);
122-
String extensionName = props.extensionNameString();
123-
deviceExtensions.add(extensionName);
124-
Logger.trace("Supported device extension [{}]", extensionName);
118+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
119+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
120+
for (int i = 0; i < numExtensions; i++) {
121+
VkExtensionProperties props = propsBuff.get(i);
122+
String extensionName = props.extensionNameString();
123+
deviceExtensions.add(extensionName);
124+
Logger.trace("Supported device extension [{}]", extensionName);
125+
}
126+
125127
}
126128
}
127129
return deviceExtensions;

booksamples/appendix-02/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
115115
int numExtensions = numExtensionsBuf.get(0);
116116
Logger.trace("Device supports [{}] extensions", numExtensions);
117117

118-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
119-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
120-
for (int i = 0; i < numExtensions; i++) {
121-
VkExtensionProperties props = propsBuff.get(i);
122-
String extensionName = props.extensionNameString();
123-
deviceExtensions.add(extensionName);
124-
Logger.trace("Supported device extension [{}]", extensionName);
118+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
119+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
120+
for (int i = 0; i < numExtensions; i++) {
121+
VkExtensionProperties props = propsBuff.get(i);
122+
String extensionName = props.extensionNameString();
123+
deviceExtensions.add(extensionName);
124+
Logger.trace("Supported device extension [{}]", extensionName);
125+
}
126+
125127
}
126128
}
127129
return deviceExtensions;

booksamples/chapter-02/src/main/java/org/vulkanb/Main.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import org.tinylog.Logger;
44
import org.vulkanb.eng.*;
5-
import org.vulkanb.eng.graph.Render;
6-
import org.vulkanb.eng.scene.Scene;
7-
import org.vulkanb.eng.wnd.Window;
85

96
public class Main implements IGameLogic {
107

booksamples/chapter-03/src/main/java/org/vulkanb/Main.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import org.tinylog.Logger;
44
import org.vulkanb.eng.*;
5-
import org.vulkanb.eng.graph.Render;
6-
import org.vulkanb.eng.scene.Scene;
7-
import org.vulkanb.eng.wnd.Window;
85

96
public class Main implements IGameLogic {
107

@@ -14,7 +11,7 @@ public static void main(String[] args) {
1411
Logger.info("Started application");
1512
engine.run();
1613
}
17-
14+
1815
@Override
1916
public void cleanup() {
2017
// To be implemented

booksamples/chapter-03/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
7272
int numExtensions = numExtensionsBuf.get(0);
7373
Logger.trace("Device supports [{}] extensions", numExtensions);
7474

75-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
76-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
77-
for (int i = 0; i < numExtensions; i++) {
78-
VkExtensionProperties props = propsBuff.get(i);
79-
String extensionName = props.extensionNameString();
80-
deviceExtensions.add(extensionName);
81-
Logger.trace("Supported device extension [{}]", extensionName);
75+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
76+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
77+
for (int i = 0; i < numExtensions; i++) {
78+
VkExtensionProperties props = propsBuff.get(i);
79+
String extensionName = props.extensionNameString();
80+
deviceExtensions.add(extensionName);
81+
Logger.trace("Supported device extension [{}]", extensionName);
82+
}
83+
8284
}
8385
}
8486
return deviceExtensions;

booksamples/chapter-04/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
7272
int numExtensions = numExtensionsBuf.get(0);
7373
Logger.trace("Device supports [{}] extensions", numExtensions);
7474

75-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
76-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
77-
for (int i = 0; i < numExtensions; i++) {
78-
VkExtensionProperties props = propsBuff.get(i);
79-
String extensionName = props.extensionNameString();
80-
deviceExtensions.add(extensionName);
81-
Logger.trace("Supported device extension [{}]", extensionName);
75+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
76+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
77+
for (int i = 0; i < numExtensions; i++) {
78+
VkExtensionProperties props = propsBuff.get(i);
79+
String extensionName = props.extensionNameString();
80+
deviceExtensions.add(extensionName);
81+
Logger.trace("Supported device extension [{}]", extensionName);
82+
}
83+
8284
}
8385
}
8486
return deviceExtensions;

booksamples/chapter-05/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
8282
int numExtensions = numExtensionsBuf.get(0);
8383
Logger.trace("Device supports [{}] extensions", numExtensions);
8484

85-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
86-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
87-
for (int i = 0; i < numExtensions; i++) {
88-
VkExtensionProperties props = propsBuff.get(i);
89-
String extensionName = props.extensionNameString();
90-
deviceExtensions.add(extensionName);
91-
Logger.trace("Supported device extension [{}]", extensionName);
85+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
86+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
87+
for (int i = 0; i < numExtensions; i++) {
88+
VkExtensionProperties props = propsBuff.get(i);
89+
String extensionName = props.extensionNameString();
90+
deviceExtensions.add(extensionName);
91+
Logger.trace("Supported device extension [{}]", extensionName);
92+
}
93+
9294
}
9395
}
9496
return deviceExtensions;

booksamples/chapter-06/src/main/java/org/vulkanb/eng/graph/vk/Device.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ private static Set<String> getDeviceExtensions(PhysDevice physDevice) {
8282
int numExtensions = numExtensionsBuf.get(0);
8383
Logger.trace("Device supports [{}] extensions", numExtensions);
8484

85-
var propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
86-
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
87-
for (int i = 0; i < numExtensions; i++) {
88-
VkExtensionProperties props = propsBuff.get(i);
89-
String extensionName = props.extensionNameString();
90-
deviceExtensions.add(extensionName);
91-
Logger.trace("Supported device extension [{}]", extensionName);
85+
try (var propsBuff = VkExtensionProperties.calloc(numExtensions)) {
86+
vkEnumerateDeviceExtensionProperties(physDevice.getVkPhysicalDevice(), (String) null, numExtensionsBuf, propsBuff);
87+
for (int i = 0; i < numExtensions; i++) {
88+
VkExtensionProperties props = propsBuff.get(i);
89+
String extensionName = props.extensionNameString();
90+
deviceExtensions.add(extensionName);
91+
Logger.trace("Supported device extension [{}]", extensionName);
92+
}
93+
9294
}
9395
}
9496
return deviceExtensions;

0 commit comments

Comments
 (0)