Skip to content

Commit 849f5d2

Browse files
committed
Select API target based on device/instance properties
1 parent 4714a3d commit 849f5d2

7 files changed

Lines changed: 44 additions & 20 deletions

File tree

src/main/java/git/artdeell/artvk/IntVMA.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
import org.lwjgl.util.vma.Vma;
99
import org.lwjgl.util.vma.VmaAllocatorCreateInfo;
1010
import org.lwjgl.util.vma.VmaVulkanFunctions;
11-
import org.lwjgl.vulkan.VK11;
1211
import org.lwjgl.vulkan.VkAllocationCallbacks;
1312
import org.lwjgl.vulkan.VkDevice;
1413

1514
public class IntVMA {
1615
public final long ptr;
1716
private final VkAllocationCallbacks allocationCallbacks;
1817

19-
public IntVMA(VkDevice vkDevice) throws BackendCreationException {
18+
public IntVMA(VkDevice vkDevice, int apiVersion) throws BackendCreationException {
2019
try (MemoryStack stack = MemoryStack.stackPush()) {
2120
VmaVulkanFunctions vmaVulkanFunctions = VmaVulkanFunctions.calloc(stack).set(vkDevice.getPhysicalDevice().getInstance(), vkDevice);
2221
allocationCallbacks = VkAllocationCallbacks.calloc();
@@ -25,7 +24,7 @@ public IntVMA(VkDevice vkDevice) throws BackendCreationException {
2524
allocationCallbacks.pfnReallocation(this::reallocate);
2625
VmaAllocatorCreateInfo createInfo = VmaAllocatorCreateInfo.calloc(stack)
2726
.instance(vkDevice.getPhysicalDevice().getInstance())
28-
.vulkanApiVersion(VK11.VK_API_VERSION_1_1)
27+
.vulkanApiVersion(apiVersion)
2928
.device(vkDevice)
3029
.physicalDevice(vkDevice.getPhysicalDevice())
3130
.pVulkanFunctions(vmaVulkanFunctions)

src/main/java/git/artdeell/artvk/Vk11Backend.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@
2727

2828
@Environment(EnvType.CLIENT)
2929
public class Vk11Backend implements GpuBackend {
30+
public static final String NAME = "ArtVK";
3031
public static final Set<String> REQUIRED_DEVICE_EXTENSIONS = Set.of(
3132
"VK_KHR_swapchain"
3233
);
3334

3435
@Override
3536
public @NotNull String getName() {
36-
return "ArtVK";
37-
}
37+
return NAME;
38+
}
3839

3940
@Override
4041
public void setWindowHints() {
@@ -76,7 +77,11 @@ public void handleWindowCreationErrors(final GLFWErrorCapture.@Nullable Error er
7677
instance = new Vk11Instance(debugOptions.logLevel(), useDebugLabels, validation);
7778
physicalDevice = findPhysicalDevice(instance);
7879
device = createVkDevice(physicalDevice);
79-
vma = new IntVMA(device);
80+
// VMA calls Vulkan APIs so pick the lowest of either the instance or device version
81+
vma = new IntVMA(
82+
device,
83+
Math.min(instance.apiTarget, physicalDevice.normalizedApiVersion())
84+
);
8085
} catch (BackendCreationException e) {
8186
if(vma != null) vma.close();
8287

@@ -127,7 +132,7 @@ private static Vk11PhysicalDevice findPhysicalDevice(final Vk11Instance instance
127132
firstDevice = currentDevice;
128133
}
129134

130-
if (isDeviceSuitable(currentDevice)) {
135+
if (isDeviceSuitable(instance, currentDevice)) {
131136
if (selectedDevice == null) {
132137
selectedDevice = currentDevice;
133138
} else if (isDeviceDiscrete(currentDevice) && !isDeviceDiscrete(selectedDevice)) {
@@ -151,9 +156,9 @@ private static Vk11PhysicalDevice findPhysicalDevice(final Vk11Instance instance
151156
return new Vk11PhysicalDevice(selectedDevice, instance.propertiesMode);
152157
}
153158

154-
private static boolean isDeviceSuitable(final VkPhysicalDevice vkPhysicalDevice) throws BackendCreationException {
159+
private static boolean isDeviceSuitable(final Vk11Instance instance, final VkPhysicalDevice vkPhysicalDevice) throws BackendCreationException {
155160
try (
156-
Vk11PhysicalDevice physicalDevice = new Vk11PhysicalDevice(vkPhysicalDevice, Vk11PhysicalDevice.PROPERTIES_VK11);
161+
Vk11PhysicalDevice physicalDevice = new Vk11PhysicalDevice(vkPhysicalDevice, instance.propertiesMode);
157162
) {
158163
String deviceName = physicalDevice.properties().deviceName();
159164
Set<String> missingExtensions = physicalDevice.getMissingExtensions(REQUIRED_DEVICE_EXTENSIONS);

src/main/java/git/artdeell/artvk/Vk11Device.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
import java.nio.ByteBuffer;
2626
import java.util.Collections;
2727
import java.util.HashMap;
28-
import java.util.HashSet;
2928
import java.util.IdentityHashMap;
3029
import java.util.List;
3130
import java.util.Map;
3231
import java.util.OptionalDouble;
33-
import java.util.Set;
3432
import java.util.function.Supplier;
3533
import net.fabricmc.api.EnvType;
3634
import net.fabricmc.api.Environment;
@@ -49,7 +47,7 @@ public class Vk11Device implements GpuDeviceBackend {
4947
private final VkDevice vkDevice;
5048
private final IntVMA vmaObj;
5149
private final long vma;
52-
private final Vk11GlslCompiler glslCompiler = new Vk11GlslCompiler();
50+
private final Vk11GlslCompiler glslCompiler;
5351
private final DeviceInfo deviceInfo;
5452
private final Vk11Queue graphicsQueue;
5553
private final Vk11Queue computeQueue;
@@ -71,10 +69,11 @@ public Vk11Device(
7169
this.instance = instance;
7270
this.vkDevice = vkDevice;
7371
this.vmaObj = vma;
72+
// The GLSL compiler doesn't call Vulkan APIs so we only care about the device version
73+
this.glslCompiler = new Vk11GlslCompiler(physicalDevice.normalizedApiVersion());
7474
this.vma = vmaObj.ptr;
75-
Set<String> extensionNames = new HashSet<>();
7675

77-
Vk11PhysicalDevice.Properties properties = physicalDevice.properties();
76+
Vk11PhysicalDevice.Properties properties = physicalDevice.properties();
7877
features = physicalDevice.features();
7978

8079
if(!features.fillModeNonSolid()) ArtVK.LOGGER.warn("Device does not support fillModeNonSolid, wireframe rendering won't work");
@@ -84,7 +83,7 @@ public Vk11Device(
8483
physicalDevice.vendorName(),
8584
properties.driverInfo(),
8685
true,
87-
"ArtVK",
86+
Vk11Backend.NAME,
8887
properties.timestampPeriod(),
8988
new DeviceLimits(
9089
features.samplerAnisotropy() ? properties.maxSamplerAnisotropy() : 1,
@@ -95,7 +94,7 @@ public Vk11Device(
9594
properties.maxColorAttachments()
9695
),
9796
new DeviceFeatures(true, features.multiDraw(), false, features.multiDrawIndirect(), true, true, true),
98-
Collections.unmodifiableSet(extensionNames),
97+
Collections.emptySet(), // TODO: maybe implement this?
9998
new HintsAndWorkarounds(false, false),
10099
physicalDevice.deviceType()
101100
);

src/main/java/git/artdeell/artvk/Vk11GlslCompiler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616
import org.lwjgl.system.MemoryUtil;
1717
import org.lwjgl.util.spvc.Spv;
1818
import org.lwjgl.util.shaderc.Shaderc;
19-
import org.lwjgl.vulkan.VK11;
2019

2120
@Environment(EnvType.CLIENT)
2221
public class Vk11GlslCompiler implements AutoCloseable {
2322
private final long shaderCompiler = Shaderc.shaderc_compiler_initialize();
2423
private final long shaderOptions = Shaderc.shaderc_compile_options_initialize();
2524
private final ShaderDefines globalDefines;
2625

27-
public Vk11GlslCompiler() {
28-
Shaderc.shaderc_compile_options_set_target_env(this.shaderOptions, Shaderc.shaderc_target_env_vulkan, VK11.VK_API_VERSION_1_1);
26+
public Vk11GlslCompiler(int apiTarget) {
27+
Shaderc.shaderc_compile_options_set_target_env(this.shaderOptions, Shaderc.shaderc_target_env_vulkan, apiTarget);
2928
Shaderc.shaderc_compile_options_set_auto_bind_uniforms(this.shaderOptions, true);
3029
Shaderc.shaderc_compile_options_set_auto_map_locations(this.shaderOptions, true);
3130
Shaderc.shaderc_compile_options_set_generate_debug_info(this.shaderOptions);

src/main/java/git/artdeell/artvk/Vk11Instance.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,21 @@ public class Vk11Instance implements AutoCloseable {
2828
private static final int ENGINE_VERSION = 0;
2929
private final VkInstance vkInstance;
3030
private final Vk11Debug debug;
31+
public final int apiTarget;
3132
public final byte propertiesMode;
3233

3334
protected Vk11Instance(final int debugVerbosity, boolean wantsDebugLabels, final boolean validation) throws BackendCreationException {
3435
try (MemoryStack stack = MemoryStack.stackPush()) {
3536
boolean vk10 = isVk10Impl();
37+
if(vk10) apiTarget = VK10.VK_API_VERSION_1_0;
38+
else apiTarget = getApiTarget(stack);
3639
VkApplicationInfo appInfo = VkApplicationInfo.calloc(stack)
3740
.sType$Default()
3841
.pApplicationName(stack.UTF8(APPLICATION_NAME))
3942
.applicationVersion(APPLICATION_VERSION)
4043
.pEngineName(stack.UTF8(ENGINE_NAME))
4144
.engineVersion(ENGINE_VERSION)
42-
.apiVersion(vk10 ? VK10.VK_API_VERSION_1_0 : VK12.VK_API_VERSION_1_2);
45+
.apiVersion(apiTarget);
4346
List<String> validationLayers = this.getSupportedValidationLayers();
4447
PointerBuffer requiredLayers = null;
4548
if (validation) {
@@ -120,6 +123,12 @@ protected Vk11Instance(final int debugVerbosity, boolean wantsDebugLabels, final
120123
}
121124
}
122125

126+
private int getApiTarget(MemoryStack stack) throws BackendCreationException {
127+
IntBuffer version = stack.callocInt(1);
128+
Vk11Utils.throwIfFailure(VK11.vkEnumerateInstanceVersion(version), "Failed to get instance API version", BackendCreationException.Reason.VULKAN_INSTANCE_CREATION_FAILED);
129+
return Vk11Utils.normalizeApiVersion(version.get(0));
130+
}
131+
123132
private boolean isVk10Impl() {
124133
long addr = VK10.vkGetInstanceProcAddr(null, "vkEnumerateInstanceVersion");
125134
return addr == 0L;

src/main/java/git/artdeell/artvk/Vk11PhysicalDevice.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ public boolean hasDeviceExtension(final String name) {
161161
return this.vkDeviceExtensions.stream().anyMatch(e -> e.extensionNameString().equals(name));
162162
}
163163

164+
public int normalizedApiVersion() {
165+
return Vk11Utils.normalizeApiVersion(properties.apiVersion);
166+
}
167+
164168
public Set<String> getMissingExtensions(final Collection<String> required) {
165169
Set<String> remaining = new HashSet<>(required);
166170

src/main/java/git/artdeell/artvk/Vk11Utils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import net.fabricmc.api.EnvType;
55
import net.fabricmc.api.Environment;
66
import org.joml.Vector4fc;
7+
import org.lwjgl.vulkan.VK10;
8+
import org.lwjgl.vulkan.VK11;
9+
import org.lwjgl.vulkan.VK12;
710
import org.lwjgl.vulkan.VkClearColorValue;
811

912
import java.util.Collection;
@@ -56,6 +59,12 @@ public static String resultToString(final int error) {
5659
};
5760
}
5861

62+
public static int normalizeApiVersion(int apiVersion) {
63+
if(apiVersion >= VK12.VK_API_VERSION_1_2) return VK12.VK_API_VERSION_1_2;
64+
if(apiVersion >= VK11.VK_API_VERSION_1_1) return VK11.VK_API_VERSION_1_1;
65+
return VK10.VK_API_VERSION_1_0;
66+
}
67+
5968
public static void parentClose(Collection<Dependent> dependents) {
6069
for(Dependent dependent : dependents) dependent.parentClosed();
6170
}

0 commit comments

Comments
 (0)