Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions module.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ neoForge {
systemProperty('neoforge.enabledGameTestNamespaces', project.mod_id)
systemProperty('neoforge.enabledGameTestNamespaces', project.mod_id)
systemProperty("alrEnableDebugContext", "true")
// systemProperty("alrUseIntelBindlessImageArrayWorkaround", "2")
jvmArgument("-XX:+UseParallelGC")
jvmArgument("-XX:+UnlockDiagnosticVMOptions")
jvmArgument("-XX:+DebugNonSafepoints")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ public class ALROptions {
public static final String OCCLUSION_CULLING_FORCE_IMPL = getProperty("alrOcclusionCullingForceImplementation", null);
public static final boolean TEXTURE_DEBUG_CLEAR = getPropertyBoolean("alrTextureDebugClear", false);
public static final boolean DEBUG_CONTEXT = getPropertyBoolean("alrEnableDebugContext", false);
// public static final int USE_INTEL_BINDLESS_IMAGE_ARRAY_WORKAROUND = getPropertyInt("alrUseIntelBindlessImageArrayWorkaround", 0);

public static void logAllOptions() {
log.info("ALR options: SPD_OPTION_WAVE_INTEROP_LDS={}, OCCLUSION_QUERY_USE_FRUSTUM_PRE_PASS={}, OCCLUSION_CULLING_FORCE_IMPL={}, TEXTURE_DEBUG_CLEAR={}",
// + ", USE_INTEL_BINDLESS_IMAGE_ARRAY_WORKAROUND={}",
SPD_OPTION_WAVE_INTEROP_LDS,
OCCLUSION_QUERY_USE_FRUSTUM_PRE_PASS,
OCCLUSION_CULLING_FORCE_IMPL,
TEXTURE_DEBUG_CLEAR
// , USE_INTEL_BINDLESS_IMAGE_ARRAY_WORKAROUND
);
}

Expand All @@ -33,6 +36,18 @@ private static boolean getPropertyBoolean(String key, boolean defaultValue) {
return !"false".equals(prop);
}

private static int getPropertyInt(String key, int defaultValue) {
String prop = System.getProperty(key);
if (prop == null) {
return defaultValue;
}
try {
return Integer.parseInt(prop);
} catch (NumberFormatException ignored) {
return defaultValue;
}
}

private static boolean getPropertyBoolean(String key) {
String prop = System.getProperty(key);
return !"false".equals(prop);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

@ApiStatus.Internal
public record ALRHIHeuristics(
boolean isWindowsArcGraphics
boolean isWindowsIntelGraphics
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public int getUniformLocation(String name, ALRGpuDeviceBackendExtension device)
int orDefault = this.uniformLocationCache.getOrDefault(name, -2);
if (orDefault == -2){
orDefault = device.alrGetUniformLocation(this, owner, name);
System.out.println("uniformName = " + name);
System.out.println("uniformLocation = " + orDefault);
this.uniformLocationCache.put(name, orDefault);
}
return orDefault;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import org.jetbrains.annotations.ApiStatus;
import org.lwjgl.opengl.ARBBindlessTexture;
import org.lwjgl.opengl.GL46;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;

import java.nio.LongBuffer;
import java.util.List;

@ApiStatus.Internal
Expand Down Expand Up @@ -126,6 +129,12 @@ public void alrBindTextureHandleMultiple(
String name,
List<TextureHandle> handle
) {
// Windows intel drivers has the wrong implementation of `glUniformHandleui64vARB`
if (this.backendExtension.alrhiCreateHeuristics().isWindowsIntelGraphics()) {
this.alrBindTextureHandleMultipleIntelBaseLocation(namedUniformAccess, name, handle);
return;
}

int uniformLocation = namedUniformAccess.getUniformLocation(name, this.backendExtension);

long[] handles = new long[handle.size()];
Expand All @@ -137,6 +146,57 @@ public void alrBindTextureHandleMultiple(
ARBBindlessTexture.glUniformHandleui64vARB(uniformLocation, handles);
}

/// Queries each array element by name; requires element names to be accepted by NamedUniformAccess.
private void alrBindTextureHandleMultipleIntel(
NamedUniformAccess namedUniformAccess,
String name,
List<TextureHandle> handle
) {
int i = 0;
for (TextureHandle textureHandle : handle) {
String uniformName = name + "[" + i++ + "]";
int uniformLocation = namedUniformAccess.getUniformLocation(uniformName, this.backendExtension);
if (uniformLocation == -1) {
continue;
}
ARBBindlessTexture.glUniformHandleui64ARB(uniformLocation, handleId(textureHandle));
}
}

/// Query the location of array uniform as base location and set each element separately
private void alrBindTextureHandleMultipleIntelBaseLocation(
NamedUniformAccess namedUniformAccess,
String name,
List<TextureHandle> handle
) {
int i = 0;
int locationStart = namedUniformAccess.getUniformLocation(name, this.backendExtension);
if (locationStart == -1) return;
for (TextureHandle textureHandle : handle) {
ARBBindlessTexture.glUniformHandleui64ARB(locationStart + i++, handleId(textureHandle));
}
}

/// Pads the input array
private void alrBindTextureHandleMultipleIntelPadded(
NamedUniformAccess namedUniformAccess,
String name,
List<TextureHandle> handle
) {
int uniformLocation = namedUniformAccess.getUniformLocation(name, this.backendExtension);

try (MemoryStack stack = MemoryStack.stackPush()) {
int count = handle.size();
LongBuffer padded = stack.mallocLong(count * 2);
for (int i = 0; i < count; i++) {
padded.put(i * 2, handleId(handle.get(i)));
padded.put(i * 2 + 1, handleId(handle.get(i)));
}

ARBBindlessTexture.nglUniformHandleui64vARB(uniformLocation, count, MemoryUtil.memAddress(padded));
}
}

@SuppressWarnings("resource")
@Override
public void alrTextureDisposed(GpuTexture texture) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import com.mojang.blaze3d.GpuOutOfMemoryException;
import com.mojang.blaze3d.opengl.GlConst;
import com.mojang.blaze3d.opengl.GlDebugLabel;
import com.mojang.blaze3d.opengl.GlDevice;
import com.mojang.blaze3d.opengl.GlStateManager;
import com.mojang.blaze3d.opengl.GlTexture;
import com.mojang.blaze3d.platform.GLX;
import com.mojang.blaze3d.preprocessor.GlslPreprocessor;
import com.mojang.blaze3d.textures.GpuTexture;
import dev.anvilcraft.lib.v2.rendering.ALROptions;
import dev.anvilcraft.lib.v2.rendering.extension.blaze3d.ALRGpuDeviceBackendExtension;
import dev.anvilcraft.lib.v2.rendering.extension.blaze3d.ALRHICapabilities;
import dev.anvilcraft.lib.v2.rendering.extension.blaze3d.ALRHIHeuristics;
Expand Down Expand Up @@ -38,12 +36,11 @@
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Locale;
import java.util.function.Supplier;

@Mixin(targets = "com.mojang.blaze3d.opengl.GlDevice")
@Mixin(GlDevice.class)
public abstract class GlDeviceMixin implements ALRGpuDeviceBackendExtension {

@Shadow
Expand Down Expand Up @@ -145,32 +142,25 @@ public ALRHICapabilities alrhiCreateCapabilities() {
@Override
public ALRHIHeuristics alrhiCreateHeuristics() {
if (this.alr$heuristics == null) {
this.alr$heuristics = new ALRHIHeuristics(this.alr$isWindowsArcGraphics());
this.alr$heuristics = new ALRHIHeuristics(this.alr$isWindowsIntelGraphics());
}
return this.alr$heuristics;
}

@Unique
private boolean alr$isWindowsArcGraphics() {
private boolean alr$isWindowsIntelGraphics() {
if (Util.getPlatform() != Util.OS.WINDOWS) {
return false;
}
String renderer = this.getRenderer();
String lowerRenderer = renderer.toLowerCase(Locale.ROOT);
if (!lowerRenderer.contains("intel")) {
return false;
}
String cpuInfo = GLX._getCpuInfo();
String lowerCpuInfo = cpuInfo.toLowerCase(Locale.ROOT);
boolean windowsArcGraphics = lowerRenderer.contains("arc")
|| (lowerCpuInfo.contains("intel") && lowerCpuInfo.contains("ultra"));
String vendor = GL11.glGetString(GL11.GL_VENDOR);
boolean windowsIntelGraphics = vendor != null && vendor.toLowerCase(Locale.ROOT).contains("intel");
LOGGER.info(
"Windows graphics info: renderer='{}', cpu='{}', windowsArcGraphics={}",
renderer,
cpuInfo,
windowsArcGraphics
"Windows graphics info: renderer='{}', vendor='{}', windowsIntelGraphics={}",
this.getRenderer(),
vendor,
windowsIntelGraphics
);
return windowsArcGraphics;
return windowsIntelGraphics;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package dev.anvilcraft.lib.v2.rendering.optimization.occlusion.hiz;

import dev.anvilcraft.lib.v2.rendering.extension.blaze3d.ALRGpuDeviceExtension;
import dev.anvilcraft.lib.v2.rendering.optimization.occlusion.hiz.spd.SinglePassDownsampler;
import org.jetbrains.annotations.ApiStatus;

/// Device policy for the hierarchical-Z backend.
///
/// The {@link dev.anvilcraft.lib.v2.rendering.optimization.occlusion.hiz.spd.SinglePassDownsampler SPD pass}
/// The {@link SinglePassDownsampler SPD pass}
/// and the Hi-Z occlusion test bind their mip chain either as consecutive image
/// units, or - on devices that cannot spare that many units - through a bindless
/// image array:
Expand All @@ -15,9 +16,8 @@
/// `layout(binding = N)` index that is not below `GL_MAX_IMAGE_UNITS`.
/// {@link #REQUIRED_IMAGE_UNITS} is the smallest power of two that satisfies
/// this requirement.
/// - The bindless fallback is what makes hierarchical-Z usable on devices with
/// fewer image units, but it is broken on Intel Arc graphics under Windows:
/// the driver advertises `GL_ARB_bindless_texture`, yet using it crashes the JVM.
/// - The bindless fallback makes hierarchical-Z usable on devices with fewer
/// image units. Windows Intel image arrays use the per-element upload workaround.
@ApiStatus.Internal
public final class HierarchicalZSupport {
/// `GL_MAX_IMAGE_UNITS` needed to bind the SPD mip chain as image units.
Expand Down Expand Up @@ -46,8 +46,7 @@ public static boolean hasEnoughImageUnits(ALRGpuDeviceExtension device) {
/// @return `true` when the bindless path has to be and may be used
public static boolean useBindlessTexturing(ALRGpuDeviceExtension device) {
return !hasEnoughImageUnits(device)
&& device.alrhiCreateCapabilities().bindlessTexturing()
&& !device.alrhiCreateHeuristics().isWindowsArcGraphics();
&& device.alrhiCreateCapabilities().bindlessTexturing();
}

/// Returns whether hierarchical-Z can run on the device at all.
Expand Down
Loading