Refactor instance validation layers selection
This commit is contained in:
parent
9f713edf62
commit
c09b04dc81
2 changed files with 106 additions and 60 deletions
|
@ -6,6 +6,8 @@ import org.lwjgl.system.*;
|
|||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import fr.mrdev023.vulkan_java.vk.utils.InstanceValidationLayersSelector;
|
||||
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -42,23 +44,16 @@ public class Instance {
|
|||
.apiVersion(VK_API_VERSION_1_1);
|
||||
|
||||
// Validation layers
|
||||
List<String> validationLayers = getSupportedValidationLayers();
|
||||
int numValidationLayers = validationLayers.size();
|
||||
boolean supportsValidation = validate;
|
||||
if (validate && numValidationLayers == 0) {
|
||||
supportsValidation = false;
|
||||
Logger.warn(
|
||||
"Request validation but no supported validation layers found. Falling back to no validation");
|
||||
}
|
||||
Logger.debug("Validation: {}", supportsValidation);
|
||||
var validationLayers = new InstanceValidationLayersSelector()
|
||||
.withValidationLayers(validate)
|
||||
.selectValidationLayers();
|
||||
|
||||
// Set required layers
|
||||
PointerBuffer requiredLayers = null;
|
||||
if (supportsValidation) {
|
||||
requiredLayers = stack.mallocPointer(numValidationLayers);
|
||||
for (int i = 0; i < numValidationLayers; i++) {
|
||||
Logger.debug("Using validation layer [{}]", validationLayers.get(i));
|
||||
requiredLayers.put(i, stack.ASCII(validationLayers.get(i)));
|
||||
if (!validationLayers.isEmpty()) {
|
||||
requiredLayers = stack.mallocPointer(validationLayers.size());
|
||||
for (String layer : validationLayers) {
|
||||
requiredLayers.put(stack.ASCII(layer));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +69,7 @@ public class Instance {
|
|||
|
||||
boolean usePortability = instanceExtensions.contains(PORTABILITY_EXTENSION) &&
|
||||
VulkanUtils.getOS() == VulkanUtils.OSType.MACOS;
|
||||
if (supportsValidation) {
|
||||
if (!validationLayers.isEmpty()) {
|
||||
ByteBuffer vkDebugUtilsExtension = stack.UTF8(EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
int numExtensions = usePortability ? glfwExtensions.remaining() + 2 : glfwExtensions.remaining() + 1;
|
||||
requiredExtensions = stack.mallocPointer(numExtensions);
|
||||
|
@ -93,7 +88,7 @@ public class Instance {
|
|||
requiredExtensions.flip();
|
||||
|
||||
long extension = MemoryUtil.NULL;
|
||||
if (supportsValidation) {
|
||||
if (!validationLayers.isEmpty()) {
|
||||
debugUtils = createDebugCallBack();
|
||||
extension = debugUtils.address();
|
||||
}
|
||||
|
@ -114,7 +109,7 @@ public class Instance {
|
|||
vkInstance = new VkInstance(pInstance.get(0), instanceInfo);
|
||||
|
||||
vkDebugHandle = VK_NULL_HANDLE;
|
||||
if (supportsValidation) {
|
||||
if (!validationLayers.isEmpty()) {
|
||||
LongBuffer longBuff = stack.mallocLong(1);
|
||||
vkCheck(vkCreateDebugUtilsMessengerEXT(vkInstance, debugUtils, null, longBuff),
|
||||
"Error creating debug utils");
|
||||
|
@ -177,49 +172,6 @@ public class Instance {
|
|||
return instanceExtensions;
|
||||
}
|
||||
|
||||
private List<String> getSupportedValidationLayers() {
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
IntBuffer numLayersArr = stack.callocInt(1);
|
||||
vkEnumerateInstanceLayerProperties(numLayersArr, null);
|
||||
int numLayers = numLayersArr.get(0);
|
||||
Logger.debug("Instance supports [{}] layers", numLayers);
|
||||
|
||||
VkLayerProperties.Buffer propsBuf = VkLayerProperties.calloc(numLayers, stack);
|
||||
vkEnumerateInstanceLayerProperties(numLayersArr, propsBuf);
|
||||
List<String> supportedLayers = new ArrayList<>();
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
VkLayerProperties props = propsBuf.get(i);
|
||||
String layerName = props.layerNameString();
|
||||
supportedLayers.add(layerName);
|
||||
Logger.debug("Supported layer [{}]", layerName);
|
||||
}
|
||||
|
||||
List<String> layersToUse = new ArrayList<>();
|
||||
|
||||
// Main validation layer
|
||||
if (supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
|
||||
layersToUse.add("VK_LAYER_KHRONOS_validation");
|
||||
return layersToUse;
|
||||
}
|
||||
|
||||
// Fallback 1
|
||||
if (supportedLayers.contains("VK_LAYER_LUNARG_standard_validation")) {
|
||||
layersToUse.add("VK_LAYER_LUNARG_standard_validation");
|
||||
return layersToUse;
|
||||
}
|
||||
|
||||
// Fallback 2 (set)
|
||||
List<String> requestedLayers = new ArrayList<>();
|
||||
requestedLayers.add("VK_LAYER_GOOGLE_threading");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_parameter_validation");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_object_tracker");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_core_validation");
|
||||
requestedLayers.add("VK_LAYER_GOOGLE_unique_objects");
|
||||
|
||||
return requestedLayers.stream().filter(supportedLayers::contains).toList();
|
||||
}
|
||||
}
|
||||
|
||||
public VkInstance getVkInstance() {
|
||||
return vkInstance;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package fr.mrdev023.vulkan_java.vk.utils;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VK10;
|
||||
import org.lwjgl.vulkan.VkLayerProperties;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
public class InstanceValidationLayersSelector {
|
||||
private boolean withValidationLayers = false;
|
||||
|
||||
public InstanceValidationLayersSelector withValidationLayers(boolean withValidationLayers) {
|
||||
this.withValidationLayers = withValidationLayers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<String> selectValidationLayers() {
|
||||
if (!withValidationLayers) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
var supportedLayers = getSupportedValidationLayers();
|
||||
log("Supported validation layers", supportedLayers);
|
||||
|
||||
var layersToUse = selectValidationLayersFromSupportedLayers(supportedLayers);
|
||||
log("Selected validation layers", layersToUse);
|
||||
|
||||
if (layersToUse.isEmpty() && withValidationLayers) {
|
||||
Logger.warn("Request validation but no supported validation layers found. Falling back to no validation");
|
||||
}
|
||||
|
||||
return layersToUse;
|
||||
}
|
||||
|
||||
private List<String> getSupportedValidationLayers() {
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
// Get the number of supported validation layers by the current vulkan instance
|
||||
IntBuffer numLayersArr = stack.callocInt(1);
|
||||
VK10.vkEnumerateInstanceLayerProperties(numLayersArr, null);
|
||||
int numLayers = numLayersArr.get(0);
|
||||
|
||||
// Get the supported validation layers by the current vulkan instance
|
||||
VkLayerProperties.Buffer propsBuf = VkLayerProperties.calloc(numLayers, stack);
|
||||
VK10.vkEnumerateInstanceLayerProperties(numLayersArr, propsBuf);
|
||||
|
||||
// Convert the supported validation layers to a list of strings
|
||||
List<String> supportedLayers = new ArrayList<>();
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
VkLayerProperties props = propsBuf.get(i);
|
||||
String layerName = props.layerNameString();
|
||||
supportedLayers.add(layerName);
|
||||
}
|
||||
|
||||
return supportedLayers;
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> selectValidationLayersFromSupportedLayers(List<String> supportedLayers) {
|
||||
List<String> layersToUse = new ArrayList<>();
|
||||
|
||||
// Main validation layer
|
||||
if (supportedLayers.contains("VK_LAYER_KHRONOS_validation")) {
|
||||
layersToUse.add("VK_LAYER_KHRONOS_validation");
|
||||
return layersToUse;
|
||||
}
|
||||
|
||||
// Fallback 1
|
||||
if (supportedLayers.contains("VK_LAYER_LUNARG_standard_validation")) {
|
||||
layersToUse.add("VK_LAYER_LUNARG_standard_validation");
|
||||
return layersToUse;
|
||||
}
|
||||
|
||||
// Fallback 2 (set)
|
||||
List<String> requestedLayers = new ArrayList<>();
|
||||
requestedLayers.add("VK_LAYER_GOOGLE_threading");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_parameter_validation");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_object_tracker");
|
||||
requestedLayers.add("VK_LAYER_LUNARG_core_validation");
|
||||
requestedLayers.add("VK_LAYER_GOOGLE_unique_objects");
|
||||
|
||||
return requestedLayers.stream().filter(supportedLayers::contains).toList();
|
||||
}
|
||||
|
||||
private void log(String title, List<String> layers) {
|
||||
Logger.debug("{} ({})", title, layers.size());
|
||||
for (String layer : layers) {
|
||||
Logger.debug(" - {}", layer);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue