This commit is contained in:
Florian RICHER 2025-05-23 13:04:00 +02:00
parent 6e0b69947c
commit 0e181376b4
5 changed files with 51 additions and 65 deletions

View file

@ -1,5 +1,5 @@
{
description = "Portfolio hugo configuration";
description = "LWJGL configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
@ -21,16 +21,14 @@
config.allowUnfree = true;
};
buildInputs = with pkgs; [ vulkan-headers vulkan-loader vulkan-validation-layers renderdoc ];
librairies = with pkgs; [ vulkan-headers vulkan-loader vulkan-validation-layers renderdoc ];
java = pkgs.jdk22;
mkCustomShell = { extraPkgs ? [] }: pkgs.mkShell {
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath librairies;
VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d:${pkgs.renderdoc}/share/vulkan/implicit_layer.d";
JAVA_HOME = java;
packages = with pkgs; [
java
maven

View file

@ -8,7 +8,6 @@ import org.tinylog.Logger;
import fr.mrdev023.vulkan_java.vk.utils.SuitablePhysicalDeviceFinder;
import java.nio.*;
import java.util.*;
import static fr.mrdev023.vulkan_java.vk.VulkanError.vkCheck;
import static org.lwjgl.vulkan.VK11.*;
@ -17,6 +16,7 @@ public class Device {
private final PhysicalDevice physicalDevice;
private final VkDevice vkDevice;
private final Queue.PresentQueue presentQueue;
private final Queue.GraphicsQueue graphicsQueue;
private final Queue.ComputeQueue computeQueue;
private final Queue.TransferQueue transferQueue;
@ -25,17 +25,10 @@ public class Device {
this.physicalDevice = physicalDeviceMatch.physicalDevice;
try (MemoryStack stack = MemoryStack.stackPush()) {
// Define required extensions
Set<String> deviceExtensions = getDeviceExtensions();
boolean usePortability = deviceExtensions
.contains(KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)
&& VulkanUtils.getOS() == VulkanUtils.OSType.MACOS;
int numExtensions = usePortability ? 2 : 1;
PointerBuffer requiredExtensions = stack.mallocPointer(numExtensions);
requiredExtensions.put(stack.ASCII(KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME));
if (usePortability) {
requiredExtensions.put(stack.ASCII(KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME));
var extensions = physicalDeviceMatch.validatorResult.deviceExtensionsResult.matchingExtensions;
PointerBuffer requiredExtensions = stack.mallocPointer(extensions.size());
for (String extension : extensions) {
requiredExtensions.put(stack.ASCII(extension));
}
requiredExtensions.flip();
@ -66,9 +59,13 @@ public class Device {
"Failed to create device");
vkDevice = new VkDevice(pp.get(0), physicalDevice.getVkPhysicalDevice(), deviceCreateInfo);
// graphicsQueue = new Queue.GraphicsQueue(this, physicalDeviceMatch.graphicsQueueFamilyIndex, 0);
// computeQueue = new Queue.ComputeQueue(this, physicalDeviceMatch.computeQueueFamilyIndex, 1);
// transferQueue = new Queue.TransferQueue(this, physicalDeviceMatch.transferQueueFamilyIndex, 2);
// graphicsQueue = new Queue.GraphicsQueue(this,
// physicalDeviceMatch.graphicsQueueFamilyIndex, 0);
// computeQueue = new Queue.ComputeQueue(this,
// physicalDeviceMatch.computeQueueFamilyIndex, 1);
// transferQueue = new Queue.TransferQueue(this,
// physicalDeviceMatch.transferQueueFamilyIndex, 2);
presentQueue = null;
graphicsQueue = null;
computeQueue = null;
transferQueue = null;
@ -82,36 +79,6 @@ public class Device {
vkDestroyDevice(vkDevice, null);
}
private Set<String> getDeviceExtensions() throws VulkanError {
Set<String> deviceExtensions = new HashSet<>();
try (MemoryStack stack = MemoryStack.stackPush()) {
// Get the number of device extensions
IntBuffer numExtensionsBuf = stack.callocInt(1);
int result = vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null,
numExtensionsBuf,
null);
vkCheck(result, "Failed to enumerate device extension properties");
int numExtensions = numExtensionsBuf.get(0);
Logger.debug("Vulkan device supported extensions ({}):", numExtensions);
// Get the device extensions
VkExtensionProperties.Buffer propsBuff = VkExtensionProperties.calloc(numExtensions, stack);
result = vkEnumerateDeviceExtensionProperties(physicalDevice.getVkPhysicalDevice(), (String) null,
numExtensionsBuf,
propsBuff);
vkCheck(result, "Failed to enumerate device extension properties");
for (int i = 0; i < numExtensions; i++) {
VkExtensionProperties props = propsBuff.get(i);
String extensionName = props.extensionNameString();
deviceExtensions.add(extensionName);
Logger.debug("\t - {}", extensionName);
}
}
return deviceExtensions;
}
public PhysicalDevice getPhysicalDevice() {
return physicalDevice;
}
@ -124,6 +91,10 @@ public class Device {
vkDeviceWaitIdle(vkDevice);
}
public Queue.PresentQueue getPresentQueue() {
return presentQueue;
}
public Queue.GraphicsQueue getGraphicsQueue() {
return graphicsQueue;
}

View file

@ -36,6 +36,12 @@ public class Queue {
}
}
public static class PresentQueue extends Queue {
public PresentQueue(Device device, int queueFamilyIndex, int queueIndex) {
super(device, queueFamilyIndex, queueIndex);
}
}
public static class ComputeQueue extends Queue {
public ComputeQueue(Device device, int queueFamilyIndex, int queueIndex) {
super(device, queueFamilyIndex, queueIndex);

View file

@ -8,6 +8,7 @@ import java.util.Optional;
import java.util.Set;
import org.lwjgl.vulkan.KHRDynamicRendering;
import org.lwjgl.vulkan.KHRPortabilitySubset;
import org.lwjgl.vulkan.KHRSwapchain;
import org.lwjgl.vulkan.VK10;
@ -28,13 +29,19 @@ public class Vulkan {
instance = new Instance(true);
surface = new Surface(instance, Display.getWindow());
var physicalDeviceCompatibilityValidator = new PhysicalDeviceCompatibilityValidator(
VK10.VK_QUEUE_GRAPHICS_BIT | VK10.VK_QUEUE_COMPUTE_BIT | VK10.VK_QUEUE_TRANSFER_BIT,
Set.of(KHRDynamicRendering.VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME),
Optional.of(surface)
);
var extensions = Set.of(KHRDynamicRendering.VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME);
if (VulkanUtils.getOS() == VulkanUtils.OSType.MACOS) {
extensions.add(KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
}
var physicalDeviceMatch = SuitablePhysicalDeviceFinder.findBestPhysicalDevice(instance, physicalDeviceCompatibilityValidator);
var physicalDeviceCompatibilityValidator = new PhysicalDeviceCompatibilityValidator(
VK10.VK_QUEUE_GRAPHICS_BIT | VK10.VK_QUEUE_COMPUTE_BIT | VK10.VK_QUEUE_TRANSFER_BIT,
extensions,
Optional.of(surface));
var physicalDeviceMatch = SuitablePhysicalDeviceFinder.findBestPhysicalDevice(instance,
physicalDeviceCompatibilityValidator);
if (physicalDeviceMatch == null) {
throw new RuntimeException("No suitable physical device found");
}

View file

@ -14,25 +14,26 @@ public class QueueFamilyRequirementsValidator {
public QueueFamilyRequirementsValidator(List<IQueueFamilyRequirement> requirements) {
this.requirements = requirements;
}
/**
* Validate the queue family requirements of the physical device.
*
* <i>Note: This method return a Result to adapt the requirements to the physical device properties after the validation.</i>
* <i>Note: This method return a Result to adapt the requirements to the
* physical device properties after the validation.</i>
*
* @param physicalDevice The physical device to validate the requirements for.
* @return A result object containing the validation results and whether the physical device is suitable.
* @return A result object containing the validation results and whether the
* physical device is suitable.
*/
public Result validate(PhysicalDevice physicalDevice) {
var vkQueueFamilyProps = physicalDevice.getVkQueueFamilyProps();
HashMap<IQueueFamilyRequirement, Optional<Integer>> result = requirements.stream()
.collect(Collectors.toMap(
requirement -> requirement,
requirement -> Optional.empty(),
(a, b) -> a,
HashMap::new
));
requirement -> requirement,
requirement -> Optional.empty(),
(a, b) -> a,
HashMap::new));
for (int i = 0; i < vkQueueFamilyProps.capacity(); i++) {
var vkQueueFamilyProp = vkQueueFamilyProps.get(i);
@ -41,12 +42,15 @@ public class QueueFamilyRequirementsValidator {
if (result.get(requirement).isPresent()) {
continue;
}
if (requirement.isFamilySuitable(physicalDevice, vkQueueFamilyProp, i)) {
result.put(requirement, Optional.of(i));
}
}
if (result.values().stream().allMatch(Optional::isPresent)) {
break;
}
}
boolean isSuitable = result.values().stream().allMatch(Optional::isPresent);