![VulkanMod](https://media.forgecdn.net/avatars/thumbnails/561/294/256/256/637913373178716740.png)
Swapchain related exception (index out of bounds)
Etaash-mathamsetty opened this issue ยท 18 comments
as of commit a6c4be6 and the changes made in my PR #58, vulkan mod crashes after rendering about 5 frames.
it seems to be trying to get frame index 3 from the swapchain buffers with size 3 (which would be out of bounds obviously), in Drawer.java
at line 170
maybe related to the incorrect frame ordering that this mod has
java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3
at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) ~[?:?]
at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) ~[?:?]
at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) ~[?:?]
at java.util.Objects.checkIndex(Objects.java:359) ~[?:?]
at java.util.ArrayList.get(ArrayList.java:427) ~[?:?]
at net.vulkanmod.vulkan.Drawer.initiateRenderPass(Drawer.java:170) ~[main/:?]
at net.minecraft.client.MinecraftClient.handler$zef000$beginRender(MinecraftClient.java:4496) ~[[email protected]:?]
at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1110) ~[[email protected]:?]
at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:737) [[email protected]:?]
at net.minecraft.client.main.Main.main(Main.java:236) [[email protected]:?]
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.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:416) [fabric-loader-0.13.3.jar:?]
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:77) [fabric-loader-0.13.3.jar:?]
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) [fabric-loader-0.13.3.jar:?]
at net.fabricmc.devlaunchinjector.Main.main(Main.java:86) [dev-launch-injector-0.2.1+build.8.jar:?]
---- Minecraft Crash Report ----
// There are four lights!
Time: 8/21/22, 12:17 AM
Description: Unexpected error
java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at net.vulkanmod.vulkan.Drawer.initiateRenderPass(Drawer.java:170)
at net.minecraft.client.MinecraftClient.handler$zef000$beginRender(MinecraftClient.java:4496)
at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1110)
at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:737)
at net.minecraft.client.main.Main.main(Main.java:236)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:416)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:77)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
-- Head --
Thread: Render thread
Stacktrace:
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at net.vulkanmod.vulkan.Drawer.initiateRenderPass(Drawer.java:170)
-- Last reload --
Details:
Reload number: 1
Reload reason: initial
Finished: No
Packs: Default, Fabric Mods
Stacktrace:
at net.minecraft.client.resource.ResourceReloadLogger.addReloadSection(ResourceReloadLogger.java:49)
at net.minecraft.client.MinecraftClient.addDetailsToCrashReport(MinecraftClient.java:2383)
at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:761)
at net.minecraft.client.main.Main.main(Main.java:236)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:416)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:77)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
-- System Details --
Details:
Minecraft Version: 1.18.2
Minecraft Version ID: 1.18.2
Operating System: Linux (amd64) version 5.19.2-zen1-1-zen
Java Version: 17.0.4, Amazon.com Inc.
Java VM Version: OpenJDK 64-Bit Server VM (mixed mode, sharing), Amazon.com Inc.
Memory: 743346128 bytes (708 MiB) / 2109734912 bytes (2012 MiB) up to 4028628992 bytes (3842 MiB)
CPUs: 8
Processor Vendor: AuthenticAMD
Processor Name: AMD Ryzen 7 4700U with Radeon Graphics
Identifier: AuthenticAMD Family 23 Model 96 Stepping 1
Microarchitecture: unknown
Frequency (GHz): -0.00
Number of physical packages: 1
Number of physical CPUs: 8
Number of logical CPUs: 8
Graphics card #0 name: Renoir
Graphics card #0 vendor: Advanced Micro Devices, Inc. [AMD/ATI] (0x1002)
Graphics card #0 VRAM (MB): 258.00
Graphics card #0 deviceId: 0x1636
Graphics card #0 versionInfo: unknown
Virtual memory max (MB): 15681.50
Virtual memory used (MB): 12613.09
Swap memory total (MB): 8000.00
Swap memory used (MB): 2947.21
JVM Flags: 0 total;
Seems odd, line 78 MAX_FRAMES_IN_FLIGHT = getSwapChainImages().size();
and currentFrame
varies between 0 and MAX_FRAMES_IN_FLIGHT
, latest commits did not change that logic.
As discussed previously i tested frame index on windows, which is fine, and linux(mesa), which seems to retrieve the wrong swapchain index from vkAcquireNextImageKHR
. Unless i'm wrong there's an issue with mesa drivers.
Now that bug shouldn't be correlated anyway to IndexOutOfBoundsException
you are getting.
Fixed by setting the frame queue size in vulkanmod settings.json to a number bigger than (or equal to) 5 with vsync on
It seems to be happening only on linux. Can you try debugging it? I can't get why currentFrame
goes out of range.
It seems to be happening only on linux. Can you try debugging it? I can't get why
currentFrame
goes out of range.
seems like not enough Swapchain frame buffers are created, there should be 5 when there actually are only 2 (becase frameQueueSize is 2)
that's why setting frameQueueSize to 5 fixes the problem since MAX_FRAMES_IN_FLIGHT is set to 5 for some reason on initialization.
After this, you run into the incorrect frame ordering bug, which still hasn't been fixed lol
Also, I have been running the game with RADV_DEBUG=hang
this entire time, since this mod causes a GPU reset (screen goes black and the gpu is essentially bricked until you restart the PC) on launch (this is one of the 2 applications that causes this, the other one has some kind of engine bug, so im assuming the same here), so it would be nice if you looked into that as well
I would genuinely recommend trying to dualboot linux on one of your machines to test, the drivers on linux are functioning as they are supposed to and usually when stuff like this happens, it's usually some kind of spec being broken, the windows drivers might not care since they are significantly more lenient towards these things than the linux drivers. (or it could be a driver bug nobody has found, a possibility since only RADV is affected, from what I have seen)
Interesting, right now i can't test it on linux but anyway it seems not every linux system is affected.
I'm still struggling to understand how commandBuffers
and inFlightFences
size is 5 since those are created with the same parameter as Swapchain framebuffers last i checked.
This type of issue should happen in every system tested not just linux, it's not a driver error or at least not directly
Interesting, right now i can't test it on linux but anyway it seems not every linux system is affected. I'm still struggling to understand how
commandBuffers
andinFlightFences
size is 5 since those are created with the same parameter as Swapchain framebuffers last i checked. This type of issue should happen in every system tested not just linux, it's not a driver error or at least not directly
the size of swapchain framebuffers is dynamic, the value of MAX_FRAMES_IN_FLIGHT is not, it is initialized once, and left alone. If the size of swapchain framebuffers changes, it causes a desync, leading to the current problem. If we are able to get rid of this desync problem, then im pretty sure the incorrect frame ordering and this bug will get resolved since I don't think it's possible to mess up the order of 2 frames (unless something is seriously wrong in the code)
Not really. MAX_FRAMES_IN_FLIGHT
is set with getSwapChainImages().size()
which is set by
Vulkan:510 IntBuffer imageCount = stack.ints(frameQueueSize);
So unless something really bad is happening at line 512 it shouldn't be a different value then config value.
I'll add a check anyway on next commit.
Not really.
MAX_FRAMES_IN_FLIGHT
is set withgetSwapChainImages().size()
which is set byVulkan:510 IntBuffer imageCount = stack.ints(frameQueueSize);
So unless something really bad is happening at line 512 it shouldn't be a different value then config value. I'll add a check anyway on next commit.
I debugged it though, MAX_FRAMES_IN_FLIGHT was 5, and then the size of getSwapChainImages reduced to 2 some time after that (it's a dynamic array, size and change any time), causing desync
But
frameQueueSize
is final
yeah, that's why the array goes down to 2 elements after 2-3 frames. While the others remain at 5 elements and MAX_FRAMES_IN_FLIGHT is still 5 for some reason
I'd like to note that changing frameQueueSize in my vulkanmod_settings.json does fix the immediate crash, but it gets ~10 FPS and is very stuttery (probably not related to this issue?)
AMD Radeon RX 570 4GB, using the org.freedesktop.Platform//22.08
I mentioned this earlier as well, the only number that worked for me last time I checked was 5, I am going to try to fix this by using a static array instead of a dynamic one (which is what it should have been in the first place)
I think the better solution would be to figure out why the MAX_FRAMES_IN_FLIGHT value is 5 in the first place when it shouldn't be 5
ok so between frame 0 and frame 1, the size of getSwapChainImages() changes from 5 to 2 (for who knows why), then by frame 3, we are out of bounds
after more debugging, I realized that the problem is initial swapchain creation, something fishy is going on there
ok so vkGetSwapchainImagesKHR seems to set imageCount to 5 and everything derails after that
ok essentially what's happening according to the vulkan docs is that 5 images are available in the swapchain, causing vkGetSwapchainImagesKHR to return 5 and then we know what happens after that I hope
ok so we are passing in a minImageCount of 2 to vkCreateSwapchainKHR, but vulkanmod incorrectly assumes that this minImageCount is going to be exactly equal to the amount of images the swapchain creates (which is not what the docs say, it's only a minimum, https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreateSwapchainKHR.html), so RADV allocates 5 images instead and I think I have explained enough for you to understand what happens from here @xCollateral
this is more of a hack but it gets the job done:
patch.txt (alternatively, just clone this https://github.com/Etaash-mathamsetty/VulkanMod)
unfortunately frame ordering is still incorrect when vsync is off, but we can fix that later
I'd like to note that changing frameQueueSize in my vulkanmod_settings.json does fix the immediate crash, but it gets ~10 FPS and is very stuttery (probably not related to this issue?)
AMD Radeon RX 570 4GB, using the org.freedesktop.Platform//22.08
here's why it was 5 images in the first place: https://gitlab.freedesktop.org/apinheiro/mesa/-/issues/9
Maybe it respects the spec, though it doesn't make a lot of sense as forcing image count will increase resources use and input lag.
Other driver address this correctly by using whatever image count is set.
Maybe it respects the spec, though it doesn't make a lot of sense as forcing image count will increase resources use and input lag. Other driver address this correctly by using whatever image count is set.
did you read the code (in the MR, I changed it)? I literally just took the number that getSwapChainImages and made sure it doesn't desync with the sizes of arrays in other classes. This is more of a sanity change rather than a bug inducing change, and I am not forcing an image count anywhere in the new patch
all the drivers here are allocating the minimum (or more), it's impossible to define a set number of images to allocate