Iris & Oculus Flywheel Compat

Iris & Oculus Flywheel Compat

18M Downloads

1.20.1 - EXCEPTION_ACCESS_VIOLATION when using Create

artman41 opened this issue ยท 6 comments

commented

Originally reported on the Flywheel issues page: Engine-Room/Flywheel#272


Describe the Bug

When using shaders, flywheel can crash with EXCEPTION_ACCESS_VIOLATION in the Render thread.

Mod Version
Create 1.20.1 0.5.1j
Flywheel 1.20.1 0.6.11-13
Oculus 1.20.1 1.7.0
Oculus Flywheel Compat 1.20.1 1.1.4
Embeddium 1.20.1 0.3.31

Reproduction Steps

  1. Launch a minecraft world using Oculus & Create
  2. Place a Flywheel rendered block (like the crusher)
  3. Enable shaders
  4. Wait for the crash, sometimes instant, sometimes can take a while

Expected Result

No crash

Operating System

Windows 11

What is your GPU?

Nvidia Geforce RTX 4090

Minecraft Version

1.20.1

Loader Version

Forge 47.3.12

Additional Context

latest.log
hs_err_pid19892.log

commented

For reference, this is the pack I'm playing with some others which is having the issues

https://www.curseforge.com/minecraft/modpacks/tekkit-from-wish

commented

Another crash - both hs_err_pid logs seem to point at

being the culprit
hs_err_pid27832.log

Might be worth adding some debug logging that we can enable via config to try and determine where the error is occuring and maybe the stacktrace?

commented

Another log with hopefully a bit more info in since I enabled minidumps

hs_err_pid70844.log

commented

Replicated the issue with a custom jar

modified code

@Override
    public void writeVertex(VertexList list, int i) {
        if(buffer.isReadOnly()) {
            IrisFlw.LOGGER.error("Buffer is readonly!");
            return;
        }
        IrisFlw.LOGGER.info("Buffer Capacity: {}", buffer.capacity());

        float x = list.getX(i);
        float y = list.getY(i);
        float z = list.getZ(i);

        float xN = list.getNX(i);
        float yN = list.getNY(i);
        float zN = list.getNZ(i);

        float u = list.getU(i);
        float v = list.getV(i);

        byte r = list.getR(i);
        byte g = list.getG(i);
        byte b = list.getB(i);
        byte a = list.getA(i);

        int light = list.getLight(i);

        putFloat(ptr, 0, x);
        putFloat(ptr, 4, y);
        putFloat(ptr, 8, z);
        putByte(ptr, 12, r);
        putByte(ptr, 13, g);
        putByte(ptr, 14, b);
        putByte(ptr, 15, a);
        putFloat(ptr, 16, u);
        putFloat(ptr, 20, v);
        putInt(ptr, 24, light << 8); // light is packed in the low byte of each short
        putByte(ptr, 28, RenderMath.nb(xN));
        putByte(ptr, 29, RenderMath.nb(yN));
        putByte(ptr, 30, RenderMath.nb(zN));
        if (list instanceof IrisBlockVertexReader irisVertexList) {
            float midU = irisVertexList.getMidTexU(i);
            float midV = irisVertexList.getMidTexV(i);

            int tangent = irisVertexList.getTangent(i);
            tangent = repackTangent(tangent);

            int midBlock = irisVertexList.getMidBlock(i);
            midBlock = repackMidBlock(midBlock);

            short entityX = irisVertexList.getEntityX(i);
            short entityY = irisVertexList.getEntityY(i);

            putFloat(ptr, 32, midU);
            putFloat(ptr, 36, midV);
            putFloat(ptr, 40, Float.intBitsToFloat(tangent));
            putFloat(ptr, 44, Float.intBitsToFloat(midBlock));

            putShort(ptr, 48, entityX);
            putShort(ptr, 50, entityY);
        } else {
            putLong(ptr, 32, 0);
            putLong(ptr, 40, 0);
            putInt(ptr, 48, 0);
        }

        ptr += ExtendedBlockVertex.EXTEND_FORMAT.getStride();
        advance();
    }

    private int repackTangent(int packedTangent) {
        // Add 1.0f to each component to avoid negative values
        var x = NormI8.unpackX(packedTangent) + 1.0f;
        var y = NormI8.unpackY(packedTangent) + 1.0f;
        var z = NormI8.unpackZ(packedTangent) + 1.0f;
        var w = NormI8.unpackW(packedTangent) + 1.0f;
        return NormI8.pack(x, y, z, w);
    }

    private int repackMidBlock(int midBlock) {
        // Add 2.0f to each component to avoid negative values
        float x = (midBlock & 0xFF) * 0.015625F + 2.0f;
        float y = ((midBlock >> 8) & 0xFF) * 0.015625F + 2.0f;
        float z = ((midBlock >> 16) & 0xFF) * 0.015625F + 2.0f;
        int emission = (midBlock >> 24) & 0xFF;

        return (int)(x * 64.0F) & 255 | ((int)(y * 64.0F) & 255) << 8 | ((int)(z * 64.0F) & 255) << 16 | emission << 24;
    }

    void putFloat(long optr, long offset, float f) {
        long ptr = optr + offset;
        IrisFlw.LOGGER.info("buffer ptr: {}, buffer pos: {}, optr: {}, offset: {}, value: {}", MemoryUtil.memAddress(buffer), buffer.position(), optr, offset, f);
        MemoryUtil.memPutFloat(ptr, f);
    }

    void putByte(long optr, long offset, byte b) {
        long ptr = optr + offset;
        IrisFlw.LOGGER.info("buffer ptr: {}, buffer pos: {}, optr: {}, offset: {}, value: {}", MemoryUtil.memAddress(buffer), buffer.position(), optr, offset, b);
        MemoryUtil.memPutByte(ptr, b);
    }

    void putInt(long optr, long offset, int i) {
        long ptr = optr + offset;
        IrisFlw.LOGGER.info("buffer ptr: {}, buffer pos: {}, optr: {}, offset: {}, value: {}", MemoryUtil.memAddress(buffer), buffer.position(), optr, offset, i);
        MemoryUtil.memPutInt(ptr, i);
    }

    void putShort(long optr, long offset, short s) {
        long ptr = optr + offset;
        IrisFlw.LOGGER.info("buffer ptr: {}, buffer pos: {}, optr: {}, offset: {}, value: {}", MemoryUtil.memAddress(buffer), buffer.position(), optr, offset, s);
        MemoryUtil.memPutShort(ptr, s);
    }

    void putLong(long optr, long offset, long l) {
        long ptr = optr + offset;
        IrisFlw.LOGGER.info("buffer ptr: {}, buffer pos: {}, optr: {}, offset: {}, value: {}", MemoryUtil.memAddress(buffer), buffer.position(), optr, offset, l);
        MemoryUtil.memPutLong(ptr, l);
    }

log

[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: Buffer Capacity: 10816
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 0, value: 0.0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 4, value: 0.0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 8, value: 0.0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 12, value: 0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 13, value: 0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 14, value: 0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 15, value: 0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 16, value: 0.0
[03Dec2024 02:14:41.898] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 20, value: 0.0
[03Dec2024 02:14:41.899] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 24, value: 0
[03Dec2024 02:14:41.899] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 28, value: 0
[03Dec2024 02:14:41.899] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 29, value: 0
[03Dec2024 02:14:41.899] [Render thread/INFO] [irisflw/]: buffer ptr: 2064680535840, buffer pos: 1248, optr: 2064680539896, offset: 30, value: 0

I've managed to consistently replicate the error by using a Shader that doesn't properly load when in the Nether & running /kill while in the nether

The error I see from Iris when it attempts to load the shader in the Nether is the following:

[03Dec2024 01:59:22.957] [Render thread/INFO] [net.minecraft.client.gui.components.ChatComponent/]: [System] [CHAT] The shaderpack failed to load! Please report the error to the shader developer. Copy Info
[03Dec2024 01:59:22.962] [Render thread/ERROR] [Oculus/]: Failed to create shader rendering pipeline, disabling shaders!
net.irisshaders.iris.gl.shader.ShaderCompileException: glint: java.lang.IllegalArgumentException: No #version directive found in source code! See debugging.md for more information.
	at net.irisshaders.iris.pipeline.transform.TransformPatcher.transformInternal(TransformPatcher.java:212) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.transform.TransformPatcher.transform(TransformPatcher.java:243) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.transform.TransformPatcher.patchVanilla(TransformPatcher.java:287) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.programs.ShaderCreator.create(ShaderCreator.java:52) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.IrisRenderingPipeline.createShader(IrisRenderingPipeline.java:699) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.IrisRenderingPipeline.createShader(IrisRenderingPipeline.java:676) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.IrisRenderingPipeline.lambda$new$12(IrisRenderingPipeline.java:422) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.programs.ShaderMap.<init>(ShaderMap.java:21) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.IrisRenderingPipeline.<init>(IrisRenderingPipeline.java:413) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.Iris.createPipeline(Iris.java:608) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.PipelineManager.preparePipeline(PipelineManager.java:33) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.minecraft.client.Minecraft.handler$zld000$oculus$iris$resetPipeline(Minecraft.java:5464) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.Minecraft.m_91324_(Minecraft.java) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.Minecraft.m_91156_(Minecraft.java:2078) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.multiplayer.ClientPacketListener.m_7992_(ClientPacketListener.java:1039) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.network.protocol.game.ClientboundRespawnPacket.m_5797_(ClientboundRespawnPacket.java:78) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.network.protocol.game.ClientboundRespawnPacket.m_5797_(ClientboundRespawnPacket.java:16) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.network.protocol.PacketUtils.m_263899_(PacketUtils.java:22) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.util.thread.BlockableEventLoop.m_6367_(BlockableEventLoop.java:156) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.util.thread.ReentrantBlockableEventLoop.m_6367_(ReentrantBlockableEventLoop.java:23) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.util.thread.BlockableEventLoop.m_7245_(BlockableEventLoop.java:130) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.util.thread.BlockableEventLoop.m_18699_(BlockableEventLoop.java:115) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.Minecraft.m_91383_(Minecraft.java:1106) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.Minecraft.m_91374_(Minecraft.java:718) ~[client-1.20.1-20230612.114412-srg.jar%23646!/:?]
	at net.minecraft.client.main.Main.main(Main.java:218) ~[forge-47.3.12.jar:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
	at net.minecraftforge.fml.loading.targets.CommonLaunchHandler.runTarget(CommonLaunchHandler.java:111) ~[fmlloader-1.20.1-47.3.12.jar:?]
	at net.minecraftforge.fml.loading.targets.CommonLaunchHandler.clientService(CommonLaunchHandler.java:99) ~[fmlloader-1.20.1-47.3.12.jar:?]
	at net.minecraftforge.fml.loading.targets.CommonClientLaunchHandler.lambda$makeService$0(CommonClientLaunchHandler.java:25) ~[fmlloader-1.20.1-47.3.12.jar:?]
	at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:30) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:53) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:71) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.Launcher.run(Launcher.java:108) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.Launcher.main(Launcher.java:78) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:26) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:23) ~[modlauncher-10.0.9.jar:?]
	at cpw.mods.bootstraplauncher.BootstrapLauncher.main(BootstrapLauncher.java:141) ~[bootstraplauncher-1.1.2.jar:?]
Caused by: java.lang.IllegalArgumentException: No #version directive found in source code! See debugging.md for more information.
	at net.irisshaders.iris.pipeline.transform.TransformPatcher$2.parseTranslationUnit(TransformPatcher.java:99) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.ASTParser.parseTranslationUnit(ASTParser.java:220) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.GroupedASTTransformer.transform(GroupedASTTransformer.java:73) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.GroupedASTTransformer.transform(GroupedASTTransformer.java:13) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.ASTTransformer.transform(ASTTransformer.java:64) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.ParameterizedTransformer.lambda$transform$0(ParameterizedTransformer.java:5) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.ParameterHolder.withJobParameters(ParameterHolder.java:21) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at io.github.douira.glsl_transformer.ast.transform.ParameterizedTransformer.transform(ParameterizedTransformer.java:5) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	at net.irisshaders.iris.pipeline.transform.TransformPatcher.transformInternal(TransformPatcher.java:208) ~[oculus-mc1.20.1-1.7.0.jar%23566!/:?]
	... 39 more

Shader wise, I'm using BeyondBeliefLegacy_V1.2.2 which I've attached
BeyondBeliefLegacy_V1.2.2.zip

Seems like if a shader doesn't properly load, it's possible for any writes at ptr+30 to fail - I assumed the buffer capacity would give an idea of the memory region occupied by the buffer but seems like I was wrong

Hopefully this helps you diagnose the issue @leon-o

Without fully understanding low-level memory management in Java, I'd assume some kind of check for whether a target pointer is within writeable memory would be the best solution

commented

I am having the same issue and would like to see a fix.

commented

Thanks for the detailed report, I also am having identical issues on newer versions of the mod and flywheel/oculus