Skip to content

Commit

Permalink
Use the swapchain maintenance extension whenever its supported to des…
Browse files Browse the repository at this point in the history
…troy old swapchains earlier
  • Loading branch information
knokko committed Dec 27, 2023
1 parent 6539713 commit eee6d49
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ public static void main(String[] args) throws InterruptedException {
commandBuffer, "SubmitDraw", waitSemaphores, fence, swapchainImage.presentSemaphore()
);

boiler.swapchains.presentImage(swapchainImage);
boiler.swapchains.presentImage(swapchainImage, fence);
frameCounter += 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static void main(String[] args) throws InterruptedException {
vkGetPhysicalDeviceFeatures2KHR(physicalDevice, features2);
return dynamicRendering.dynamicRendering() && multiview.multiview();
})
.beforeDeviceCreation((ciDevice, physicalDevice, stack) -> {
.beforeDeviceCreation((ciDevice, instanceExtensions, physicalDevice, stack) -> {
var dynamicRendering = VkPhysicalDeviceDynamicRenderingFeaturesKHR.calloc(stack);
dynamicRendering.sType$Default();
dynamicRendering.dynamicRendering(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public static void main(String[] args) throws InterruptedException {
commandBuffer, "RingApproximation", waitSemaphores, fence, swapchainImage.presentSemaphore()
);

boiler.swapchains.presentImage(swapchainImage);
boiler.swapchains.presentImage(swapchainImage, fence);
frameCounter += 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ class CameraController {
commandBuffer, "TerrainDraw", waitSemaphores, fence, swapchainImage.presentSemaphore()
);

boiler.swapchains.presentImage(swapchainImage);
boiler.swapchains.presentImage(swapchainImage, fence);
frameCounter += 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static void main(String[] args) throws InterruptedException {
) }, fence, acquired.presentSemaphore()
);

boiler.swapchains.presentImage(acquired);
boiler.swapchains.presentImage(acquired, fence);
}

counter += 1;
Expand Down
46 changes: 42 additions & 4 deletions src/main/java/com/github/knokko/boiler/builder/BoilerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,27 @@

import static com.github.knokko.boiler.builder.BoilerSwapchainBuilder.createSurface;
import static com.github.knokko.boiler.exceptions.VulkanFailureException.assertVkSuccess;
import static com.github.knokko.boiler.util.CollectionHelper.decodeStringSet;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFWVulkan.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.memUTF8;
import static org.lwjgl.vulkan.EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
import static org.lwjgl.vulkan.EXTMemoryBudget.VK_EXT_MEMORY_BUDGET_EXTENSION_NAME;
import static org.lwjgl.vulkan.EXTSurfaceMaintenance1.VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME;
import static org.lwjgl.vulkan.EXTSwapchainMaintenance1.VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME;
import static org.lwjgl.vulkan.EXTValidationFeatures.*;
import static org.lwjgl.vulkan.KHRBindMemory2.VK_KHR_BIND_MEMORY_2_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRDedicatedAllocation.VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRGetMemoryRequirements2.VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRGetPhysicalDeviceProperties2.VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRGetPhysicalDeviceProperties2.vkGetPhysicalDeviceFeatures2KHR;
import static org.lwjgl.vulkan.KHRGetSurfaceCapabilities2.VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRPortabilityEnumeration.VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK11.VK_API_VERSION_1_1;
import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2;
import static org.lwjgl.vulkan.VK12.VK_API_VERSION_1_2;
import static org.lwjgl.vulkan.VK13.VK_API_VERSION_1_3;

Expand All @@ -45,7 +51,7 @@ public class BoilerBuilder {
return new VkInstance(pInstance.get(0), ciInstance);
};

public static final VkDeviceCreator DEFAULT_VK_DEVICE_CREATOR = (ciDevice, physicalDevice, stack) -> {
public static final VkDeviceCreator DEFAULT_VK_DEVICE_CREATOR = (ciDevice, instanceExtensions, physicalDevice, stack) -> {
var pDevice = stack.callocPointer(1);
assertVkSuccess(vkCreateDevice(physicalDevice, ciDevice, null, pDevice), "CreateDevice", "BoilerBuilder");
return new VkDevice(pDevice.get(0), physicalDevice, ciDevice);
Expand Down Expand Up @@ -351,6 +357,8 @@ else throw new GLFWFailureException(
}
}

boolean[] pHasSwapchainMaintenance = { false };

if (window != 0L) {
checkMainThread();
if (!glfwVulkanSupported()) throw new GLFWFailureException("glfwVulkanSupported() returned false");
Expand All @@ -360,6 +368,36 @@ else throw new GLFWFailureException(
this.requiredVulkanInstanceExtensions.add(memUTF8(glfwExtensions.get(extensionIndex)));
}
this.requiredVulkanDeviceExtensions.add(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
this.desiredVulkanDeviceExtensions.add(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME);
this.desiredVulkanInstanceExtensions.add(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME);
this.desiredVulkanInstanceExtensions.add(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
if (apiVersion == VK_API_VERSION_1_0) {
this.desiredVulkanInstanceExtensions.add(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
}

this.beforeDeviceCreation((ciDevice, instanceExtensions, physicalDevice, stack) -> {
Set<String> deviceExtensions = decodeStringSet(ciDevice.ppEnabledExtensionNames());
if (deviceExtensions.contains(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME)) {
var swapchainFeatures = VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT.calloc(stack);
swapchainFeatures.sType$Default();

var features = VkPhysicalDeviceFeatures2.calloc(stack);
features.sType$Default();
features.pNext(swapchainFeatures);

if (apiVersion != VK_API_VERSION_1_0) {
vkGetPhysicalDeviceFeatures2(physicalDevice, features);
}
if (instanceExtensions.contains(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
vkGetPhysicalDeviceFeatures2KHR(physicalDevice, features);
}

if (swapchainFeatures.swapchainMaintenance1()) {
ciDevice.pNext(swapchainFeatures);
pHasSwapchainMaintenance[0] = true;
}
}
});
}

XrBoiler xr = null;
Expand All @@ -372,7 +410,7 @@ else throw new GLFWFailureException(
}

// Nice for VMA
if (VK_API_VERSION_MAJOR(apiVersion) == 1 && VK_API_VERSION_MINOR(apiVersion) == 0) {
if (apiVersion == VK_API_VERSION_1_0) {
this.desiredVulkanInstanceExtensions.add(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
this.desiredVulkanDeviceExtensions.add(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
this.desiredVulkanDeviceExtensions.add(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
Expand All @@ -387,14 +425,14 @@ else throw new GLFWFailureException(
}

var instanceResult = BoilerInstanceBuilder.createInstance(this);
var deviceResult = BoilerDeviceBuilder.createDevice(this, instanceResult.vkInstance());
var deviceResult = BoilerDeviceBuilder.createDevice(this, instanceResult);

var windowSurface = deviceResult.windowSurface() != 0L ?
createSurface(deviceResult.vkPhysicalDevice(), deviceResult.windowSurface()) : null;
var swapchainSettings = windowSurface != null ? swapchainBuilder.chooseSwapchainSettings(windowSurface) : null;

var instance = new BoilerInstance(
window, windowSurface, swapchainSettings, xr,
window, windowSurface, swapchainSettings, pHasSwapchainMaintenance[0], xr,
instanceResult.vkInstance(), deviceResult.vkPhysicalDevice(), deviceResult.vkDevice(),
instanceResult.enabledExtensions(), deviceResult.enabledExtensions(),
deviceResult.queueFamilies(), deviceResult.vmaAllocator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

class BoilerDeviceBuilder {

static Result createDevice(BoilerBuilder builder, VkInstance vkInstance) {
static Result createDevice(BoilerBuilder builder, BoilerInstanceBuilder.Result instanceResult) {
VkPhysicalDevice vkPhysicalDevice;
VkDevice vkDevice;
Set<String> enabledExtensions;
Expand All @@ -40,17 +40,19 @@ static Result createDevice(BoilerBuilder builder, VkInstance vkInstance) {
if (builder.window != 0L) {
var pSurface = stack.callocLong(1);
assertVkSuccess(glfwCreateWindowSurface(
vkInstance, builder.window, null, pSurface
instanceResult.vkInstance(), builder.window, null, pSurface
), "glfwCreateWindowSurface", null);
windowSurface = pSurface.get(0);
} else windowSurface = 0L;

VkPhysicalDevice[] candidateDevices = BasicDeviceFilter.getCandidates(
builder, vkInstance, windowSurface, builder.printDeviceRejectionInfo
builder, instanceResult.vkInstance(), windowSurface, builder.printDeviceRejectionInfo
);
if (candidateDevices.length == 0) throw new NoVkPhysicalDeviceException();

vkPhysicalDevice = builder.deviceSelector.choosePhysicalDevice(stack, candidateDevices, vkInstance);
vkPhysicalDevice = builder.deviceSelector.choosePhysicalDevice(
stack, candidateDevices, instanceResult.vkInstance()
);
if (vkPhysicalDevice == null) throw new NoVkPhysicalDeviceException();
}

Expand Down Expand Up @@ -186,10 +188,12 @@ static Result createDevice(BoilerBuilder builder, VkInstance vkInstance) {
if (enabledFeatures2 == null) ciDevice.pEnabledFeatures(enabledFeatures10);

for (var preCreator : builder.preDeviceCreators) {
preCreator.beforeDeviceCreation(ciDevice, vkPhysicalDevice, stack);
preCreator.beforeDeviceCreation(ciDevice, instanceResult.enabledExtensions(), vkPhysicalDevice, stack);
}

vkDevice = builder.vkDeviceCreator.vkCreateDevice(ciDevice, vkPhysicalDevice, stack);
vkDevice = builder.vkDeviceCreator.vkCreateDevice(
ciDevice, instanceResult.enabledExtensions(), vkPhysicalDevice, stack
);

var queueFamilyMap = new HashMap<Integer, QueueFamily>();
for (var entry : uniqueQueueFamilies.entrySet()) {
Expand All @@ -204,15 +208,15 @@ static Result createDevice(BoilerBuilder builder, VkInstance vkInstance) {
);

var vmaVulkanFunctions = VmaVulkanFunctions.calloc(stack);
vmaVulkanFunctions.set(vkInstance, vkDevice);
vmaVulkanFunctions.set(instanceResult.vkInstance(), vkDevice);

int vmaFlags = getVmaFlags(enabledExtensions);

var ciAllocator = VmaAllocatorCreateInfo.calloc(stack);
ciAllocator.flags(vmaFlags);
ciAllocator.physicalDevice(vkPhysicalDevice);
ciAllocator.device(vkDevice);
ciAllocator.instance(vkInstance);
ciAllocator.instance(instanceResult.vkInstance());
ciAllocator.pVulkanFunctions(vmaVulkanFunctions);
ciAllocator.vulkanApiVersion(builder.apiVersion);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
import org.lwjgl.vulkan.VkDeviceCreateInfo;
import org.lwjgl.vulkan.VkPhysicalDevice;

import java.util.Set;

@FunctionalInterface
public interface PreVkDeviceCreator {

void beforeDeviceCreation(VkDeviceCreateInfo ciDevice, VkPhysicalDevice physicalDevice, MemoryStack stack);
void beforeDeviceCreation(
VkDeviceCreateInfo ciDevice,
Set<String> enabledInstanceExtensions,
VkPhysicalDevice physicalDevice,
MemoryStack stack
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
import org.lwjgl.vulkan.VkDeviceCreateInfo;
import org.lwjgl.vulkan.VkPhysicalDevice;

import java.util.Set;

@FunctionalInterface
public interface VkDeviceCreator {

VkDevice vkCreateDevice(
VkDeviceCreateInfo ciDevice, VkPhysicalDevice physicalDevice, MemoryStack stack
VkDeviceCreateInfo ciDevice,
Set<String> enabledInstanceExtensions,
VkPhysicalDevice physicalDevice,
MemoryStack stack
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.lwjgl.vulkan.VkDeviceCreateInfo;
import org.lwjgl.vulkan.VkPhysicalDevice;

import java.util.Set;

import static com.github.knokko.boiler.exceptions.VulkanFailureException.assertVkSuccess;
import static com.github.knokko.boiler.xr.OpenXrFailureException.assertXrSuccess;
import static org.lwjgl.openxr.KHRVulkanEnable2.xrCreateVulkanDeviceKHR;
Expand All @@ -24,7 +26,10 @@ class XrDeviceCreator implements VkDeviceCreator {
}

@Override
public VkDevice vkCreateDevice(VkDeviceCreateInfo ciDevice, VkPhysicalDevice physicalDevice, MemoryStack stack) {
public VkDevice vkCreateDevice(
VkDeviceCreateInfo ciDevice, Set<String> instanceExtensions,
VkPhysicalDevice physicalDevice, MemoryStack stack
) {
var xrCiDevice = XrVulkanDeviceCreateInfoKHR.calloc(stack);
xrCiDevice.type$Default();
xrCiDevice.systemId(xrSystem);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public class BoilerInstance {
private boolean destroyed = false;

public BoilerInstance(
long glfwWindow, WindowSurface windowSurface, SwapchainSettings swapchainSettings, XrBoiler xr,
long glfwWindow, WindowSurface windowSurface, SwapchainSettings swapchainSettings,
boolean hasSwapchainMaintenance, XrBoiler xr,
VkInstance vkInstance, VkPhysicalDevice vkPhysicalDevice, VkDevice vkDevice,
Set<String> instanceExtensions, Set<String> deviceExtensions,
QueueFamilies queueFamilies, long vmaAllocator
Expand All @@ -74,7 +75,7 @@ public BoilerInstance(
this.pipelines = new BoilerPipelines(this);
this.commands = new BoilerCommands(this);
this.sync = new BoilerSync(this);
this.swapchains = swapchainSettings != null ? new BoilerSwapchains(this) : null;
this.swapchains = swapchainSettings != null ? new BoilerSwapchains(this, hasSwapchainMaintenance) : null;
this.debug = new BoilerDebug(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ public record AcquireResult(
int numSwapchainImages,
long acquireSemaphore,
long presentSemaphore,
long presentFence,
int width,
int height,
Object swapchain,
long swapchainID,
Consumer<Runnable> addPreDestructionCallback
) {
Expand Down
Loading

0 comments on commit eee6d49

Please sign in to comment.