diff --git a/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/NvidiumHelper.java b/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/NvidiumHelper.java index 9277fc90..93133e41 100644 --- a/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/NvidiumHelper.java +++ b/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/NvidiumHelper.java @@ -33,15 +33,11 @@ public static boolean isRendererActive() { } } - public static boolean shouldKeepCommandBuffer() { - if (VisorState.get().isNotActive() || !isRendererActive()) { - return false; - } - if (VRRenderState.getPhase().isVanilla()) { - return false; - } + public static int getViewSlot() { + if (VisorState.get().isNotActive() || VRRenderState.getPhase().isVanilla()) return 0; VRRenderPass renderPass = VRRenderState.getRenderPass(); - return renderPass.isWorld() && !renderPass.isEye(); + if (!renderPass.isWorld() || renderPass.isEye()) return 0; + return renderPass == VRRenderPass.CENTER ? 1 : 2; } public static void ensureVRTemporalCoherence() { diff --git a/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/mixin/RenderPipelineMixin.java b/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/mixin/RenderPipelineMixin.java index 342dfb5f..5d89bc33 100644 --- a/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/mixin/RenderPipelineMixin.java +++ b/visor-core/src/main/java/org/vmstudio/visor/compatibility/nvidium/mixin/RenderPipelineMixin.java @@ -1,58 +1,115 @@ package org.vmstudio.visor.compatibility.nvidium.mixin; +import me.cortex.nvidium.gl.RenderDevice; +import me.cortex.nvidium.gl.buffers.IDeviceMappedBuffer; +import me.cortex.nvidium.managers.SectionManager; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.vmstudio.visor.compatibility.nvidium.NvidiumHelper; @Pseudo @Mixin(targets = "me.cortex.nvidium.RenderPipeline", remap = false) public class RenderPipelineMixin { + @Shadow(remap = false) @Final @Mutable + private IDeviceMappedBuffer regionVisibility; + @Shadow(remap = false) @Final @Mutable + private IDeviceMappedBuffer sectionVisibility; + @Shadow(remap = false) @Final @Mutable + private IDeviceMappedBuffer terrainCommandBuffer; + @Shadow(remap = false) @Final @Mutable + private IDeviceMappedBuffer translucencyCommandBuffer; @Shadow(remap = false) private int prevRegionCount; + @Shadow(remap = false) @Final + private RenderDevice device; + @Shadow(remap = false) @Final + private SectionManager sectionManager; + //0 = eyes, 1 = CENTER, 2 = THIRD_PERSON @Unique - private boolean visor$keepCommands; - + private final IDeviceMappedBuffer[][] visor$views = new IDeviceMappedBuffer[3][4]; + @Unique + private final int[] visor$prevRegionCounts = new int[3]; @Unique - private int visor$savedRegionCount; + private int visor$activeSlot; @Inject(method = "renderFrame", at = @At("HEAD"), remap = false) - private void visor$captureCommandOwner(CallbackInfo ci) { - visor$keepCommands = NvidiumHelper.shouldKeepCommandBuffer(); - visor$savedRegionCount = this.prevRegionCount; + private void visor$bindViewFrame(CallbackInfo ci) { + visor$bind(); } - @ModifyArg( - method = "renderFrame", - at = @At(value = "INVOKE", - target = "Lme/cortex/nvidium/renderers/SectionRasterizer;raster(I)V"), - remap = false - ) - private int visor$skipCommandRebuild(int visibleRegions) { - return visor$keepCommands ? 0 : visibleRegions; + @Inject(method = "renderFrame", at = @At("RETURN"), remap = false) + private void visor$unbindViewFrame(CallbackInfo ci) { + visor$unbind(); } - @ModifyArg( - method = "renderFrame", - at = @At(value = "INVOKE", - target = "Lme/cortex/nvidium/renderers/TemporalTerrainRasterizer;raster(IJ)V"), - index = 0, - remap = false - ) - private int visor$skipTemporalRebuild(int visibleRegions) { - return visor$keepCommands ? 0 : visibleRegions; + @Inject(method = "renderTranslucent", at = @At("HEAD"), remap = false) + private void visor$bindViewTranslucent(CallbackInfo ci) { + visor$bind(); } - @Inject(method = "renderFrame", at = @At("RETURN"), remap = false) - private void visor$restoreCommandOwner(CallbackInfo ci) { - if (visor$keepCommands) { - this.prevRegionCount = visor$savedRegionCount; + @Inject(method = "renderTranslucent", at = @At("RETURN"), remap = false) + private void visor$unbindViewTranslucent(CallbackInfo ci) { + visor$unbind(); + } + + @Inject(method = "delete", at = @At("HEAD"), remap = false) + private void visor$deleteViewBuffers(CallbackInfo ci) { + for (int slot = 1; slot < visor$views.length; slot++) { + for (int i = 0; i < visor$views[slot].length; i++) { + if (visor$views[slot][i] == null) continue; + visor$views[slot][i].delete(); + visor$views[slot][i] = null; + } + } + } + + @Unique + private void visor$bind() { + int slot = NvidiumHelper.getViewSlot(); + if (slot == 0) return; + if (visor$views[slot][0] == null) { + long regions = sectionManager.getRegionManager().maxRegions(); + visor$views[slot][0] = device.createDeviceOnlyMappedBuffer(regions); + visor$views[slot][1] = device.createDeviceOnlyMappedBuffer(regions * 256L); + visor$views[slot][2] = device.createDeviceOnlyMappedBuffer(regions * 8L); + visor$views[slot][3] = device.createDeviceOnlyMappedBuffer(regions * 8L); } + visor$store(0); + visor$load(slot); + visor$activeSlot = slot; + } + + @Unique + private void visor$unbind() { + if (visor$activeSlot == 0) return; + visor$store(visor$activeSlot); + visor$load(0); + visor$activeSlot = 0; + } + + @Unique + private void visor$store(int slot) { + visor$views[slot][0] = regionVisibility; + visor$views[slot][1] = sectionVisibility; + visor$views[slot][2] = terrainCommandBuffer; + visor$views[slot][3] = translucencyCommandBuffer; + visor$prevRegionCounts[slot] = prevRegionCount; + } + + @Unique + private void visor$load(int slot) { + regionVisibility = visor$views[slot][0]; + sectionVisibility = visor$views[slot][1]; + terrainCommandBuffer = visor$views[slot][2]; + translucencyCommandBuffer = visor$views[slot][3]; + prevRegionCount = visor$prevRegionCounts[slot]; } } diff --git a/visor-core/src/main/java/org/vmstudio/visor/core/client/render/helpers/CullFrustumHelper.java b/visor-core/src/main/java/org/vmstudio/visor/core/client/render/helpers/CullFrustumHelper.java index 2777be5a..cc724e42 100644 --- a/visor-core/src/main/java/org/vmstudio/visor/core/client/render/helpers/CullFrustumHelper.java +++ b/visor-core/src/main/java/org/vmstudio/visor/core/client/render/helpers/CullFrustumHelper.java @@ -4,17 +4,12 @@ import org.joml.Matrix4f; import org.joml.Matrix4fc; import org.vmstudio.visor.api.client.render.VRRenderPass; -import org.vmstudio.visor.api.client.settings.VRClientSettings; -import org.vmstudio.visor.api.client.settings.enums.MirrorMode; -import org.vmstudio.visor.compatibility.nvidium.NvidiumHelper; import org.vmstudio.visor.compatibility.sodium.SodiumHelper; import org.vmstudio.visor.core.client.ClientContext; import org.vmstudio.visor.core.client.VisorState; import org.vmstudio.visor.core.client.render.VRRenderState; public class CullFrustumHelper { - private static final Matrix4f lastCenterProjection = new Matrix4f(); - private static boolean centerProjectionCaptured; private CullFrustumHelper() { throw new UnsupportedOperationException("This is an utility class and cannot be instantiated"); } @@ -27,11 +22,6 @@ public static Matrix4f widenCullProjection(Matrix4f projection) { return projection; } VRRenderPass renderPass = VRRenderState.getRenderPass(); - if (renderPass == VRRenderPass.CENTER) { - lastCenterProjection.set(projection); - centerProjectionCaptured = true; - return projection; - } if (!renderPass.isEye()) { return projection; } @@ -46,13 +36,6 @@ public static Matrix4f widenCullProjection(Matrix4f projection) { float tanDown = Math.min(tanDown(projection), Math.min(tanDown(left), tanDown(right))); float tanUp = Math.max(tanUp(projection), Math.max(tanUp(left), tanUp(right))); - if (centerProjectionCaptured && NvidiumHelper.isRendererActive() && isCenterPassActive()) { - tanLeft = Math.min(tanLeft, tanLeft(lastCenterProjection)); - tanRight = Math.max(tanRight, tanRight(lastCenterProjection)); - tanDown = Math.min(tanDown, tanDown(lastCenterProjection)); - tanUp = Math.max(tanUp, tanUp(lastCenterProjection)); - } - double cullFovMargin = Math.toRadians(5); tanLeft = expand(tanLeft, -cullFovMargin); tanRight = expand(tanRight, cullFovMargin); @@ -71,14 +54,6 @@ public static Matrix4f widenCullProjection(Matrix4f projection) { return result; } - private static boolean isCenterPassActive() { - MirrorMode mode = VRClientSettings.getMirrorMode(); - return mode == MirrorMode.FIRST_PERSON - || (mode == MirrorMode.MIXED_REALITY - && VRClientSettings.isMixedRealityWithFirstPerson() - && VRClientSettings.isMixedRealityAsGrid2x2()); - } - private static float expand(float tangent, double marginRadians) { double angle = Math.atan(tangent) + marginRadians; double maxHalfAngle = Math.toRadians(85); diff --git a/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/RenderDevice.java b/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/RenderDevice.java new file mode 100644 index 00000000..db8412bc --- /dev/null +++ b/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/RenderDevice.java @@ -0,0 +1,9 @@ +package me.cortex.nvidium.gl; + +import me.cortex.nvidium.gl.buffers.IDeviceMappedBuffer; + +public class RenderDevice { + public IDeviceMappedBuffer createDeviceOnlyMappedBuffer(long size) { + throw new UnsupportedOperationException("stub"); + } +} diff --git a/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/buffers/IDeviceMappedBuffer.java b/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/buffers/IDeviceMappedBuffer.java new file mode 100644 index 00000000..ffd8060e --- /dev/null +++ b/visor-core/stubs/src/main/java/me/cortex/nvidium/gl/buffers/IDeviceMappedBuffer.java @@ -0,0 +1,5 @@ +package me.cortex.nvidium.gl.buffers; + +public interface IDeviceMappedBuffer { + void delete(); +} diff --git a/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/RegionManager.java b/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/RegionManager.java new file mode 100644 index 00000000..99d7e68a --- /dev/null +++ b/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/RegionManager.java @@ -0,0 +1,7 @@ +package me.cortex.nvidium.managers; + +public class RegionManager { + public int maxRegions() { + throw new UnsupportedOperationException("stub"); + } +} diff --git a/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/SectionManager.java b/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/SectionManager.java new file mode 100644 index 00000000..7a55a1dd --- /dev/null +++ b/visor-core/stubs/src/main/java/me/cortex/nvidium/managers/SectionManager.java @@ -0,0 +1,7 @@ +package me.cortex.nvidium.managers; + +public class SectionManager { + public RegionManager getRegionManager() { + throw new UnsupportedOperationException("stub"); + } +}