Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ff1713f

Browse files
committedOct 29, 2021
Check for availability of VK_LAYER_KHRONOS_validation
and disable Vulkan debugging if unavailable.
1 parent 73b08c6 commit ff1713f

File tree

9 files changed

+209
-31
lines changed

9 files changed

+209
-31
lines changed
 

‎res/org/lwjgl/demo/opengl/shader/downsampling/downsample.cs.glsl

+30-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#extension GL_KHR_shader_subgroup_shuffle : require
77

88
layout(location=0) uniform sampler2D baseImage;
9-
layout(binding=0, rgba16f) uniform writeonly restrict image2D mips[3];
9+
layout(binding=0, rgba16f) uniform writeonly restrict image2D mips[5];
1010

1111
/*
1212
* The assumption here is that each subgroup item maps to its corresponding local workgroup item
@@ -30,6 +30,8 @@ int unpack(int x) {
3030
return x;
3131
}
3232

33+
shared vec4 sm[4][4];
34+
3335
void main(void) {
3436
ivec2 ts = textureSize(baseImage, 0);
3537

@@ -78,4 +80,31 @@ void main(void) {
7880
t = (t + h + v + d) * vec4(0.25);
7981
if ((gl_SubgroupInvocationID & 15) == 0)
8082
imageStore(mips[2], i/ivec2(4), t);
83+
84+
// compute mip 4 using shared memory
85+
/*
86+
* For mip 4 we essentially have 8x8 work items.
87+
*/
88+
ivec2 smc = l / ivec2(4);
89+
ivec2 smi = (smc + ivec2(1)) & ivec2(1);
90+
if ((l.x & 3) == 0 && (l.y & 3) == 0)
91+
sm[smc.x][smc.y] = t;
92+
barrier();
93+
if ((l.x & 7) == 0 && (l.y & 7) == 0) {
94+
t = (sm[smc.x][smc.y] + sm[smi.x][smc.y] + sm[smc.x][smi.y] + sm[smi.x][smi.y]) * 0.25;
95+
imageStore(mips[3], i/ivec2(8), t);
96+
}
97+
98+
// compute mip 5 also using shared memory
99+
/*
100+
* For mip 5 we have 16x16 work items.
101+
*/
102+
smc = l / ivec2(8);
103+
if ((l.x & 7) == 0 && (l.y & 7) == 0)
104+
sm[smc.x][smc.y] = t;
105+
barrier();
106+
if (l.x == 0 && l.y == 0) {
107+
t = (sm[0][0] + sm[1][0] + sm[0][1] + sm[1][1]) * 0.25;
108+
imageStore(mips[4], i/ivec2(16), t);
109+
}
81110
}

‎src/org/lwjgl/demo/opengl/shader/DownsamplingDemo.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.nio.ByteBuffer;
1515
import java.nio.IntBuffer;
1616

17+
import org.joml.Random;
1718
import org.lwjgl.demo.opengl.util.DemoUtils;
1819
import org.lwjgl.opengl.GL;
1920
import org.lwjgl.opengl.GLCapabilities;
@@ -25,6 +26,7 @@
2526
/**
2627
* Computes 3 mip levels of a texture using only a single compute shader dispatch
2728
* and GL_KHR_shader_subgroup.
29+
* Then uses shared memory for mips 4 and 5.
2830
*
2931
* @author Kai Burjack
3032
*/
@@ -97,8 +99,9 @@ private static void createComputeProgram() throws IOException {
9799
computeProgram = program;
98100
}
99101

102+
private static final Random rnd = new Random(1L);
100103
private static byte v(int i) {
101-
return i % 8 == 0 ? (byte) 255 : (byte) 0;
104+
return (byte) (rnd.nextFloat() * 255);
102105
}
103106

104107
private static void createTextures() {
@@ -108,12 +111,14 @@ private static void createTextures() {
108111
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
109112
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
110113
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
111-
glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA16F, width, height);
114+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
115+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
116+
glTexStorage2D(GL_TEXTURE_2D, 6, GL_RGBA16F, width, height);
112117
ByteBuffer pixels = MemoryUtil.memAlloc(width * height * 4);
113118
// fill the first level of the texture with some pattern
114119
for (int y = 0; y < height; y++)
115120
for (int x = 0; x < width; x++)
116-
pixels.put(v(x)).put(v(y)).put((byte) 127).put((byte) 255);
121+
pixels.put(v(x)).put(v(y)).put(v(x)).put((byte) 255);
117122
pixels.flip();
118123
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
119124
MemoryUtil.memFree(pixels);
@@ -125,10 +130,12 @@ private static void downsample() {
125130

126131
// read mip level 0
127132
glBindTexture(GL_TEXTURE_2D, texture);
128-
// write mip levels 1-3
133+
// write mip levels 1-4
129134
glBindImageTexture(0, texture, 1, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
130135
glBindImageTexture(1, texture, 2, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
131136
glBindImageTexture(2, texture, 3, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
137+
glBindImageTexture(3, texture, 4, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
138+
glBindImageTexture(4, texture, 5, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
132139

133140
int texelsPerWorkItem = 2;
134141
int numGroupsX = (int) ceil((double) width / texelsPerWorkItem / 16);
@@ -142,12 +149,14 @@ private static void downsample() {
142149
glBindImageTexture(0, 0, 1, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
143150
glBindImageTexture(1, 0, 2, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
144151
glBindImageTexture(2, 0, 3, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
152+
glBindImageTexture(3, 0, 3, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
153+
glBindImageTexture(4, 0, 3, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
145154
glUseProgram(0);
146155
}
147156

148157
private static void present() {
149158
glClear(GL_COLOR_BUFFER_BIT);
150-
glViewport(0, 0, width/(1<<level), height/(1<<level));
159+
glViewport(0, 0, width, height);
151160
glUseProgram(quadProgram);
152161
glUniform1i(levelUniform, level);
153162
glBindVertexArray(nullVao);
@@ -179,7 +188,7 @@ private static void init() throws IOException {
179188
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
180189
glfwSetWindowShouldClose(window, true);
181190
else if (key == GLFW_KEY_UP && action == GLFW_RELEASE)
182-
level = min(3, level + 1);
191+
level = min(5, level + 1);
183192
else if (key == GLFW_KEY_DOWN && action == GLFW_RELEASE)
184193
level = max(0, level - 1);
185194
});

‎src/org/lwjgl/demo/vulkan/ClearScreenDemo.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.lwjgl.demo.vulkan;
66

77
import static java.util.Arrays.asList;
8+
import static java.util.Collections.emptyList;
89
import static java.util.stream.Collectors.toList;
910
import static org.joml.Math.*;
1011
import static org.lwjgl.demo.vulkan.VKUtil.*;
@@ -187,9 +188,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
187188
}
188189
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
189190
}
190-
PointerBuffer enabledLayers = null;
191+
PointerBuffer ppEnabledLayerNames = null;
191192
if (DEBUG) {
192-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
193+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
194+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
195+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
196+
} else {
197+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
198+
}
193199
}
194200
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
195201
.calloc(stack)
@@ -198,7 +204,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
198204
.calloc(stack)
199205
.sType$Default()
200206
.apiVersion(VK_API_VERSION_1_1))
201-
.ppEnabledLayerNames(enabledLayers)
207+
.ppEnabledLayerNames(ppEnabledLayerNames)
202208
.ppEnabledExtensionNames(ppEnabledExtensionNames);
203209
PointerBuffer pInstance = stack.mallocPointer(1);
204210
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -344,6 +350,20 @@ private static DeviceAndQueueFamilies selectBestPhysicalDevice() {
344350
}
345351
}
346352

353+
private static final List<String> enumerateSupportedInstanceLayers() {
354+
try (MemoryStack stack = stackPush()) {
355+
IntBuffer pPropertyCount = stack.mallocInt(1);
356+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
357+
int count = pPropertyCount.get(0);
358+
if (count > 0) {
359+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
360+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
361+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
362+
}
363+
}
364+
return emptyList();
365+
}
366+
347367
private static VkDevice createDevice(List<String> requiredExtensions) {
348368
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
349369
for (String requiredExtension : requiredExtensions) {

‎src/org/lwjgl/demo/vulkan/raytracing/HybridMagicaVoxel.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import static java.lang.ClassLoader.getSystemResourceAsStream;
88
import static java.util.Arrays.asList;
9+
import static java.util.Collections.emptyList;
910
import static java.util.stream.Collectors.toList;
1011
import static org.joml.Math.*;
1112
import static org.lwjgl.demo.vulkan.VKUtil.*;
@@ -277,6 +278,20 @@ private static List<String> enumerateSupportedInstanceExtensions() {
277278
}
278279
}
279280

281+
private static final List<String> enumerateSupportedInstanceLayers() {
282+
try (MemoryStack stack = stackPush()) {
283+
IntBuffer pPropertyCount = stack.mallocInt(1);
284+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
285+
int count = pPropertyCount.get(0);
286+
if (count > 0) {
287+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
288+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
289+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
290+
}
291+
}
292+
return emptyList();
293+
}
294+
280295
private static VkInstance createInstance(PointerBuffer requiredExtensions) {
281296
List<String> supportedInstanceExtensions = enumerateSupportedInstanceExtensions();
282297
try (MemoryStack stack = stackPush()) {
@@ -287,9 +302,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
287302
}
288303
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
289304
}
290-
PointerBuffer enabledLayers = null;
305+
PointerBuffer ppEnabledLayerNames = null;
291306
if (DEBUG) {
292-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
307+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
308+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
309+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
310+
} else {
311+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
312+
}
293313
}
294314
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
295315
.calloc(stack)
@@ -298,7 +318,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
298318
.calloc(stack)
299319
.sType$Default()
300320
.apiVersion(VK_API_VERSION_1_2))
301-
.ppEnabledLayerNames(enabledLayers)
321+
.ppEnabledLayerNames(ppEnabledLayerNames)
302322
.ppEnabledExtensionNames(ppEnabledExtensionNames);
303323
PointerBuffer pInstance = stack.mallocPointer(1);
304324
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");

‎src/org/lwjgl/demo/vulkan/raytracing/ReflectiveMagicaVoxel.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import static java.lang.ClassLoader.getSystemResourceAsStream;
88
import static java.util.Arrays.asList;
9+
import static java.util.Collections.emptyList;
910
import static java.util.stream.Collectors.toList;
1011
import static org.joml.Math.*;
1112
import static org.lwjgl.demo.vulkan.VKUtil.*;
@@ -273,9 +274,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
273274
}
274275
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
275276
}
276-
PointerBuffer enabledLayers = null;
277+
PointerBuffer ppEnabledLayerNames = null;
277278
if (DEBUG) {
278-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
279+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
280+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
281+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
282+
} else {
283+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
284+
}
279285
}
280286
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
281287
.calloc(stack)
@@ -284,7 +290,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
284290
.calloc(stack)
285291
.sType$Default()
286292
.apiVersion(VK_API_VERSION_1_1))
287-
.ppEnabledLayerNames(enabledLayers)
293+
.ppEnabledLayerNames(ppEnabledLayerNames)
288294
.ppEnabledExtensionNames(ppEnabledExtensionNames);
289295
PointerBuffer pInstance = stack.mallocPointer(1);
290296
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -475,6 +481,20 @@ private static DeviceAndQueueFamilies selectPhysicalDevice() {
475481
}
476482
}
477483

484+
private static final List<String> enumerateSupportedInstanceLayers() {
485+
try (MemoryStack stack = stackPush()) {
486+
IntBuffer pPropertyCount = stack.mallocInt(1);
487+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
488+
int count = pPropertyCount.get(0);
489+
if (count > 0) {
490+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
491+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
492+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
493+
}
494+
}
495+
return emptyList();
496+
}
497+
478498
private static VkDevice createDevice(List<String> requiredExtensions) {
479499
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
480500
for (String requiredExtension : requiredExtensions) {

‎src/org/lwjgl/demo/vulkan/raytracing/SdfBricks.java

+26-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import static java.lang.ClassLoader.getSystemResourceAsStream;
88
import static java.util.Arrays.asList;
9+
import static java.util.Collections.emptyList;
910
import static java.util.stream.Collectors.toList;
1011
import static org.joml.Math.*;
1112
import static org.lwjgl.demo.vulkan.VKUtil.*;
@@ -271,9 +272,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
271272
}
272273
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
273274
}
274-
PointerBuffer enabledLayers = null;
275+
PointerBuffer ppEnabledLayerNames = null;
275276
if (DEBUG) {
276-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
277+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
278+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
279+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
280+
} else {
281+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
282+
}
277283
}
278284
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
279285
.calloc(stack)
@@ -282,7 +288,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
282288
.calloc(stack)
283289
.sType$Default()
284290
.apiVersion(VK_API_VERSION_1_1))
285-
.ppEnabledLayerNames(enabledLayers)
291+
.ppEnabledLayerNames(ppEnabledLayerNames)
286292
.ppEnabledExtensionNames(ppEnabledExtensionNames);
287293
PointerBuffer pInstance = stack.mallocPointer(1);
288294
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -471,6 +477,20 @@ private static DeviceAndQueueFamilies selectPhysicalDevice() {
471477
}
472478
}
473479

480+
private static final List<String> enumerateSupportedInstanceLayers() {
481+
try (MemoryStack stack = stackPush()) {
482+
IntBuffer pPropertyCount = stack.mallocInt(1);
483+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
484+
int count = pPropertyCount.get(0);
485+
if (count > 0) {
486+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
487+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
488+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
489+
}
490+
}
491+
return emptyList();
492+
}
493+
474494
private static VkDevice createDevice(List<String> requiredExtensions) {
475495
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
476496
for (String requiredExtension : requiredExtensions) {
@@ -989,7 +1009,7 @@ private static VoxelField buildVoxelField() throws IOException {
9891009
Vector3i min = new Vector3i(Integer.MAX_VALUE);
9901010
Vector3i max = new Vector3i(Integer.MIN_VALUE);
9911011
byte[] field = new byte[(256 + 2) * (256 + 2) * (256 + 2)];
992-
try (InputStream is = getSystemResourceAsStream("org/lwjgl/demo/models/mikelovesrobots_mmmm/scene_house5.vox");
1012+
try (InputStream is = getSystemResourceAsStream("voxelmodel/vox/monument/monu2.vox");
9931013
BufferedInputStream bis = new BufferedInputStream(is)) {
9941014
new MagicaVoxelLoader().read(bis, new MagicaVoxelLoader.Callback() {
9951015
public void voxel(int x, int y, int z, byte c) {
@@ -1022,8 +1042,8 @@ private static Geometry createGeometry() throws IOException {
10221042
int[] num = {0};
10231043
new GreedyVoxels(voxelField.ny, voxelField.py, voxelField.w, voxelField.d, new GreedyVoxels.Callback() {
10241044
public void voxel(int x0, int y0, int z0, int w, int h, int d, int v) {
1025-
aabbs.putFloat(x0).putFloat(y0).putFloat(z0);
1026-
aabbs.putFloat(x0+w).putFloat(y0+h+0.1f).putFloat(z0+d);
1045+
aabbs.putFloat(x0*8).putFloat(y0*9.6f).putFloat(z0*8);
1046+
aabbs.putFloat((x0+w)*8).putFloat((y0+h)*9.6f+1.8f).putFloat((z0+d)*8);
10271047
num[0]++;
10281048
}
10291049
}).merge(voxelField.field);

‎src/org/lwjgl/demo/vulkan/raytracing/SimpleSphere.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.lwjgl.demo.vulkan.raytracing;
66

77
import static java.util.Arrays.asList;
8+
import static java.util.Collections.emptyList;
89
import static java.util.stream.Collectors.toList;
910
import static java.util.stream.IntStream.range;
1011
import static org.joml.Math.*;
@@ -245,9 +246,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
245246
}
246247
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
247248
}
248-
PointerBuffer enabledLayers = null;
249+
PointerBuffer ppEnabledLayerNames = null;
249250
if (DEBUG) {
250-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
251+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
252+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
253+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
254+
} else {
255+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
256+
}
251257
}
252258
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
253259
.calloc(stack)
@@ -256,7 +262,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
256262
.calloc(stack)
257263
.sType$Default()
258264
.apiVersion(VK_API_VERSION_1_1))
259-
.ppEnabledLayerNames(enabledLayers)
265+
.ppEnabledLayerNames(ppEnabledLayerNames)
260266
.ppEnabledExtensionNames(ppEnabledExtensionNames);
261267
PointerBuffer pInstance = stack.mallocPointer(1);
262268
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -438,6 +444,20 @@ private static DeviceAndQueueFamilies selectPhysicalDevice() {
438444
}
439445
}
440446

447+
private static final List<String> enumerateSupportedInstanceLayers() {
448+
try (MemoryStack stack = stackPush()) {
449+
IntBuffer pPropertyCount = stack.mallocInt(1);
450+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
451+
int count = pPropertyCount.get(0);
452+
if (count > 0) {
453+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
454+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
455+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
456+
}
457+
}
458+
return emptyList();
459+
}
460+
441461
private static VkDevice createDevice(List<String> requiredExtensions) {
442462
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
443463
for (String requiredExtension : requiredExtensions) {

‎src/org/lwjgl/demo/vulkan/raytracing/SimpleTriangle.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.lwjgl.demo.vulkan.raytracing;
66

77
import static java.util.Arrays.asList;
8+
import static java.util.Collections.emptyList;
89
import static java.util.stream.Collectors.toList;
910
import static java.util.stream.IntStream.range;
1011
import static org.joml.Math.*;
@@ -244,9 +245,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
244245
}
245246
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
246247
}
247-
PointerBuffer enabledLayers = null;
248+
PointerBuffer ppEnabledLayerNames = null;
248249
if (DEBUG) {
249-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
250+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
251+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
252+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
253+
} else {
254+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
255+
}
250256
}
251257
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
252258
.calloc(stack)
@@ -255,7 +261,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
255261
.calloc(stack)
256262
.sType$Default()
257263
.apiVersion(VK_API_VERSION_1_1))
258-
.ppEnabledLayerNames(enabledLayers)
264+
.ppEnabledLayerNames(ppEnabledLayerNames)
259265
.ppEnabledExtensionNames(ppEnabledExtensionNames);
260266
PointerBuffer pInstance = stack.mallocPointer(1);
261267
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -439,6 +445,20 @@ private static DeviceAndQueueFamilies selectPhysicalDevice() {
439445
}
440446
}
441447

448+
private static final List<String> enumerateSupportedInstanceLayers() {
449+
try (MemoryStack stack = stackPush()) {
450+
IntBuffer pPropertyCount = stack.mallocInt(1);
451+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
452+
int count = pPropertyCount.get(0);
453+
if (count > 0) {
454+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
455+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
456+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
457+
}
458+
}
459+
return emptyList();
460+
}
461+
442462
private static VkDevice createDevice(List<String> requiredExtensions) {
443463
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
444464
for (String requiredExtension : requiredExtensions) {

‎src/org/lwjgl/demo/vulkan/raytracing/SimpleTriangleRayQuery.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.lwjgl.demo.vulkan.raytracing;
66

77
import static java.util.Arrays.asList;
8+
import static java.util.Collections.emptyList;
89
import static java.util.stream.Collectors.toList;
910
import static java.util.stream.IntStream.range;
1011
import static org.joml.Math.*;
@@ -240,9 +241,14 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
240241
}
241242
ppEnabledExtensionNames = pointers(stack, requiredExtensions, stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
242243
}
243-
PointerBuffer enabledLayers = null;
244+
PointerBuffer ppEnabledLayerNames = null;
244245
if (DEBUG) {
245-
enabledLayers = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
246+
List<String> supportedLayers = enumerateSupportedInstanceLayers();
247+
if (!supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
248+
System.err.println("DEBUG requested but layer VK_LAYER_KHRONOS_validation is unavailable. Install the Vulkan SDK for your platform. Vulkan debug layer will not be used.");
249+
} else {
250+
ppEnabledLayerNames = stack.pointers(stack.UTF8("VK_LAYER_KHRONOS_validation"));
251+
}
246252
}
247253
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo
248254
.calloc(stack)
@@ -251,7 +257,7 @@ private static VkInstance createInstance(PointerBuffer requiredExtensions) {
251257
.calloc(stack)
252258
.sType$Default()
253259
.apiVersion(VK_API_VERSION_1_1))
254-
.ppEnabledLayerNames(enabledLayers)
260+
.ppEnabledLayerNames(ppEnabledLayerNames)
255261
.ppEnabledExtensionNames(ppEnabledExtensionNames);
256262
PointerBuffer pInstance = stack.mallocPointer(1);
257263
_CHECK_(vkCreateInstance(pCreateInfo, null, pInstance), "Failed to create VkInstance");
@@ -430,6 +436,20 @@ private static DeviceAndQueueFamilies selectPhysicalDevice() {
430436
}
431437
}
432438

439+
private static final List<String> enumerateSupportedInstanceLayers() {
440+
try (MemoryStack stack = stackPush()) {
441+
IntBuffer pPropertyCount = stack.mallocInt(1);
442+
vkEnumerateInstanceLayerProperties(pPropertyCount, null);
443+
int count = pPropertyCount.get(0);
444+
if (count > 0) {
445+
VkLayerProperties.Buffer pProperties = VkLayerProperties.malloc(count, stack);
446+
vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
447+
return pProperties.stream().map(VkLayerProperties::layerNameString).collect(toList());
448+
}
449+
}
450+
return emptyList();
451+
}
452+
433453
private static VkDevice createDevice(List<String> requiredExtensions) {
434454
List<String> supportedDeviceExtensions = enumerateSupportedDeviceExtensions();
435455
for (String requiredExtension : requiredExtensions) {

0 commit comments

Comments
 (0)
Please sign in to comment.