Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
279 changes: 227 additions & 52 deletions src/main/java/rs117/hd/HdPlugin.java

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/main/java/rs117/hd/HdPluginConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,17 @@ default boolean forceIndirectDraw() {
return false;
}

String KEY_OCCLUSION_CULLING = "experimentalOcclusionCulling";
@ConfigItem(
keyName = KEY_OCCLUSION_CULLING,
name = "Occlusion Culling",
description = "",
section = experimentalSettings
)
default boolean occlusionCulling() {
return true;
}

String KEY_ASYNC_MODEL_CACHE_SIZE = "asyncModelCacheSizeMiB";
@Range(
min = 16,
Expand Down
1 change: 0 additions & 1 deletion src/main/java/rs117/hd/config/DynamicLights.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public enum DynamicLights
static {
int max = 0;
for (var e : values()) {
assert e.tiledLightingLayers % 4 == 0; // Needs to be divisible by 4
max = max(max, e.tiledLightingLayers);
}
MAX_LAYERS_PER_TILE = max;
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/rs117/hd/opengl/GLConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package rs117.hd.opengl;

import static org.lwjgl.opengl.ARBShaderImageLoadStore.GL_MAX_IMAGE_UNITS;
import static org.lwjgl.opengl.GL11C.GL_MAX_TEXTURE_SIZE;
import static org.lwjgl.opengl.GL11C.glGetInteger;
import static org.lwjgl.opengl.GL13C.GL_SAMPLES;
import static org.lwjgl.opengl.GL20C.GL_MAX_TEXTURE_IMAGE_UNITS;
import static org.lwjgl.opengl.GL30C.GL_MAX_SAMPLES;
import static org.lwjgl.opengl.GL31C.GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT;
import static org.lwjgl.opengl.GL41.GL_NUM_PROGRAM_BINARY_FORMATS;
import static rs117.hd.HdPlugin.GL_CAPS;

public class GLConstants {

private static int FORCED_SAMPLES_VALUE = -1;
public static int getForcedSamples() {
if(FORCED_SAMPLES_VALUE == -1)
FORCED_SAMPLES_VALUE = glGetInteger(GL_SAMPLES);
return FORCED_SAMPLES_VALUE;
}

private static int MAX_SAMPLES_VALUE = -1;
public static int getMaxSamples() {
if(MAX_SAMPLES_VALUE == -1)
MAX_SAMPLES_VALUE = glGetInteger(GL_MAX_SAMPLES);
return MAX_SAMPLES_VALUE;
}

private static int MAX_IMAGE_UNITS_VALUE = -1;
public static int getMaxImageUnits() {
if(!GL_CAPS.GL_ARB_shader_image_load_store)
return 0;
if(MAX_IMAGE_UNITS_VALUE == -1)
MAX_IMAGE_UNITS_VALUE = glGetInteger(GL_MAX_IMAGE_UNITS);
return MAX_IMAGE_UNITS_VALUE;
}

private static int MAX_TEXTURE_UNITS_VALUE = -1;
public static int getMaxTextureUnits() {
if(MAX_TEXTURE_UNITS_VALUE == -1)
MAX_TEXTURE_UNITS_VALUE = glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS);
return MAX_TEXTURE_UNITS_VALUE;
}

private static int MAX_TEXTURE_SIZE_VALUE = -1;
public static int getMaxTextureSize() {
if(MAX_TEXTURE_SIZE_VALUE == -1)
MAX_TEXTURE_SIZE_VALUE = glGetInteger(GL_MAX_TEXTURE_SIZE);
return MAX_TEXTURE_SIZE_VALUE;
}

private static int BUFFER_OFFSET_ALIGNMENT_VALUE = -1;
public static int getBufferOffsetAlignment() {
if(BUFFER_OFFSET_ALIGNMENT_VALUE == -1)
BUFFER_OFFSET_ALIGNMENT_VALUE = glGetInteger(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);

return BUFFER_OFFSET_ALIGNMENT_VALUE;
}

private static int NUM_PROGRAM_BINARY_FORMATS_VALUE = -1;
public static int getNumProgramBinaryFormats() {
if(NUM_PROGRAM_BINARY_FORMATS_VALUE == -1)
NUM_PROGRAM_BINARY_FORMATS_VALUE = glGetInteger(GL_NUM_PROGRAM_BINARY_FORMATS);
return NUM_PROGRAM_BINARY_FORMATS_VALUE;
}
}
23 changes: 23 additions & 0 deletions src/main/java/rs117/hd/opengl/shader/DepthShaderProgram.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package rs117.hd.opengl.shader;

import java.io.IOException;
import rs117.hd.HdPlugin;

import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
import static org.lwjgl.opengl.GL20C.GL_FRAGMENT_SHADER_DERIVATIVE_HINT;
import static org.lwjgl.opengl.GL20C.GL_VERTEX_SHADER;
import static rs117.hd.HdPlugin.GL_CAPS;
import static rs117.hd.renderer.zone.ZoneRenderer.TEXTURE_UNIT_TEXTURED_FACES;

public class DepthShaderProgram extends ShaderProgram {
public DepthShaderProgram() {
super(t -> t.add(GL_VERTEX_SHADER, "depth_vert.glsl"));
}

@Override
public void compile(ShaderIncludes includes) throws ShaderException, IOException {
if(HdPlugin.APPLE || !GL_CAPS.OpenGL46)
shaderTemplate.add(GL_FRAGMENT_SHADER, "depth_frag.glsl");
super.compile(includes);
}
}
32 changes: 32 additions & 0 deletions src/main/java/rs117/hd/opengl/shader/OcclusionShaderProgram.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package rs117.hd.opengl.shader;

import java.io.IOException;
import rs117.hd.HdPlugin;

import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
import static org.lwjgl.opengl.GL20C.GL_VERTEX_SHADER;
import static rs117.hd.HdPlugin.GL_CAPS;

public class OcclusionShaderProgram extends ShaderProgram {
public OcclusionShaderProgram() {
super(t -> t.add(GL_VERTEX_SHADER, "occlusion_vert.glsl"));
}

@Override
public void compile(ShaderIncludes includes) throws ShaderException, IOException {
if(HdPlugin.APPLE || !GL_CAPS.OpenGL46)
shaderTemplate.add(GL_FRAGMENT_SHADER, "depth_frag.glsl");
super.compile(includes);
}

public static class Debug extends OcclusionShaderProgram {
public Uniform1i queryId = addUniform1i("queryId");

@Override
public void compile(ShaderIncludes includes) throws ShaderException, IOException {
shaderTemplate.remove(GL_FRAGMENT_SHADER);
shaderTemplate.add(GL_FRAGMENT_SHADER, "occlusion_debug_frag.glsl");
super.compile(includes);
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/rs117/hd/opengl/shader/SceneShaderProgram.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.lwjgl.opengl.GL33C.*;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_GAME;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_SCENE_ALPHA_DEPTH;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_SCENE_OPAQUE_DEPTH;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_SHADOW_MAP;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_TILED_LIGHTING_MAP;
import static rs117.hd.renderer.zone.ZoneRenderer.TEXTURE_UNIT_TEXTURED_FACES;
Expand All @@ -11,6 +13,8 @@ public class SceneShaderProgram extends ShaderProgram {
protected final UniformTexture uniShadowMap = addUniformTexture("shadowMap");
protected final UniformTexture uniTiledLightingTextureArray = addUniformTexture("tiledLightingArray");
protected final UniformTexture uniTextureFaces = addUniformTexture("textureFaces");
protected final UniformTexture uniSceneOpaqueDepth = addUniformTexture("sceneOpaqueDepth");
protected final UniformTexture uniSceneAlphaDepth = addUniformTexture("sceneAlphaDepth");

public SceneShaderProgram() {
super(t -> t
Expand All @@ -25,6 +29,8 @@ protected void initialize() {
uniShadowMap.set(TEXTURE_UNIT_SHADOW_MAP);
uniTiledLightingTextureArray.set(TEXTURE_UNIT_TILED_LIGHTING_MAP);
uniTextureFaces.set(TEXTURE_UNIT_TEXTURED_FACES);
uniSceneOpaqueDepth.set(TEXTURE_UNIT_SCENE_OPAQUE_DEPTH);
uniSceneAlphaDepth.set(TEXTURE_UNIT_SCENE_ALPHA_DEPTH);
}

public static class Legacy extends SceneShaderProgram {
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/rs117/hd/opengl/shader/ShaderTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import lombok.extern.slf4j.Slf4j;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import rs117.hd.opengl.GLConstants;

import static org.lwjgl.opengl.GL33C.*;
import static rs117.hd.opengl.shader.ShaderIncludes.SHADER_DUMP_PATH;
Expand Down Expand Up @@ -103,9 +104,7 @@ public int compile(ShaderIncludes includes) throws ShaderException, IOException
ok = true;

if (SHADER_DUMP_PATH != null) {
int[] numFormats = { 0 };
glGetIntegerv(GL41C.GL_NUM_PROGRAM_BINARY_FORMATS, numFormats);
if (numFormats[0] < 1) {
if (GLConstants.getNumProgramBinaryFormats() < 1) {
log.error("OpenGL driver does not support any binary formats");
} else {
int[] size = { 0 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

import static org.lwjgl.opengl.GL33C.*;
import static rs117.hd.HdPlugin.IMAGE_UNIT_TILED_LIGHTING;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_SCENE_ALPHA_DEPTH;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_SCENE_OPAQUE_DEPTH;
import static rs117.hd.HdPlugin.TEXTURE_UNIT_TILED_LIGHTING_MAP;

public class TiledLightingShaderProgram extends ShaderProgram {
private final UniformTexture uniTiledLightingTextureArray = addUniformTexture("tiledLightingArray");
private final UniformImage uniTiledLightingTextureStore = addUniformImage("tiledLightingImage");

private final UniformTexture uniSceneOpaqueDepth = addUniformTexture("sceneOpaqueDepth");
private final UniformTexture uniSceneAlphaDepth = addUniformTexture("sceneAlphaDepth");

public TiledLightingShaderProgram() {
super(t -> t
.add(GL_VERTEX_SHADER, "tiled_lighting_vert.glsl")
Expand All @@ -20,5 +25,8 @@ public TiledLightingShaderProgram() {
protected void initialize() {
uniTiledLightingTextureArray.set(TEXTURE_UNIT_TILED_LIGHTING_MAP);
uniTiledLightingTextureStore.set(IMAGE_UNIT_TILED_LIGHTING);

uniSceneOpaqueDepth.set(TEXTURE_UNIT_SCENE_OPAQUE_DEPTH);
uniSceneAlphaDepth.set(TEXTURE_UNIT_SCENE_ALPHA_DEPTH);
}
}
2 changes: 2 additions & 0 deletions src/main/java/rs117/hd/opengl/uniforms/UBOGlobal.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public void initialize() {
public Property pointLightsCount = addProperty(PropertyType.Int, "pointLightsCount");

public Property cameraPos = addProperty(PropertyType.FVec3, "cameraPos");
public Property cameraNear = addProperty(PropertyType.Float, "cameraNear");
public Property cameraFar = addProperty(PropertyType.Float, "cameraFar");
public Property viewMatrix = addProperty(PropertyType.Mat4, "viewMatrix");
public Property projectionMatrix = addProperty(PropertyType.Mat4, "projectionMatrix");
public Property invProjectionMatrix = addProperty(PropertyType.Mat4, "invProjectionMatrix");
Expand Down
25 changes: 20 additions & 5 deletions src/main/java/rs117/hd/opengl/uniforms/UniformBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lwjgl.BufferUtils;
import rs117.hd.opengl.GLConstants;
import rs117.hd.utils.RenderState;
import rs117.hd.utils.buffer.GLBuffer;
import rs117.hd.utils.buffer.SharedGLBuffer;

import static org.lwjgl.opengl.GL33C.*;
import static rs117.hd.utils.HDUtils.align;
import static rs117.hd.utils.MathUtils.*;

@Slf4j
public abstract class UniformBuffer<GLBUFFER extends GLBuffer> {
@RequiredArgsConstructor
protected enum PropertyType {
public enum PropertyType {
Int(4, 4, 1),
IVec2(8, 8, 2),
IVec3(12, 16, 3),
Expand All @@ -35,10 +37,10 @@ protected enum PropertyType {
Mat3(48, 16, 9),
Mat4(64, 16, 16);

private final int size;
private final int alignment;
private final int elementCount;
private final boolean isInt = name().startsWith("I");
public final int size;
public final int alignment;
public final int elementCount;
public final boolean isInt = name().startsWith("I");
}

@AllArgsConstructor
Expand All @@ -47,6 +49,7 @@ public static class Property {
private UniformBuffer<?> owner;
private int position;
private int offset = -1;
@Getter
private final PropertyType type;
private final String name;

Expand Down Expand Up @@ -343,6 +346,18 @@ public void bind(int bindingIndex) {
glBindBufferBase(GL_UNIFORM_BUFFER, bindingIndex, glBuffer.id);
}

public void bindRange(Property startProperty, Property endProperty) {
assert endProperty.offset >= startProperty.offset;

long bufferAlignment = GLConstants.getBufferOffsetAlignment();
long bytesOffset = (long)startProperty.offset * Integer.BYTES;
long bytesSize = ((endProperty.offset - startProperty.offset) + align(endProperty.type.size, endProperty.type.alignment, true)) * Integer.BYTES;

long alignedBytesOffset = align(bytesOffset, bufferAlignment, false);

glBindBufferRange(GL_UNIFORM_BUFFER, bindingIndex, glBuffer.id, alignedBytesOffset, bytesSize);
}

protected void preUpload() {}

public final void upload() {
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/rs117/hd/overlays/FrameTimerOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.TitleComponent;
import rs117.hd.HdPlugin;
import rs117.hd.renderer.zone.OcclusionManager;
import rs117.hd.renderer.zone.SceneManager;
import rs117.hd.renderer.zone.WorldViewContext;
import rs117.hd.renderer.zone.ZoneRenderer;
Expand Down Expand Up @@ -206,6 +207,14 @@ public Dimension render(Graphics2D g) {
.build());
}

var occlusionManager = OcclusionManager.getInstance();
if(occlusionManager != null && occlusionManager.isActive()) {
children.add(LineComponent.builder()
.left("Visible Occlusion Queries:")
.right(String.format("%d/%d", occlusionManager.getPassedQueryCount(), occlusionManager.getQueryCount()))
.build());
}

children.add(LineComponent.builder()
.leftFont(boldFont)
.left("Streaming Stats:")
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/rs117/hd/overlays/Timer.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ public enum Timer {
DRAW_TEMP,
DRAW_POSTSCENE,
DRAW_TILED_LIGHTING,
DRAW_OCCLUSION,
DRAW_SUBMIT,

// Miscellaneous
SWAP_BUFFERS,
EXECUTE_COMMAND_BUFFER,
MAP_UI_BUFFER("Map UI Buffer"),
COPY_UI("Copy UI"),
OCCLUSION_READBACK,
MODEL_UPLOAD_COMPLETE,

// Logic
Expand Down Expand Up @@ -68,6 +70,8 @@ public enum Timer {
COMPUTE(GPU_TIMER),
UNMAP_ROOT_CTX(GPU_TIMER),
CLEAR_SCENE(GPU_TIMER),
RENDER_DEPTH_PRE_PASS(GPU_TIMER),
RENDER_OCCLUSION(GPU_TIMER),
RENDER_SHADOWS(GPU_TIMER),
RENDER_SCENE(GPU_TIMER),
RENDER_UI(GPU_TIMER, "Render UI"),
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import rs117.hd.config.ShadowMode;
import rs117.hd.overlays.FrameTimer;
import rs117.hd.overlays.Timer;
import rs117.hd.renderer.zone.OcclusionManager.OcclusionQuery;
import rs117.hd.scene.ModelOverrideManager;
import rs117.hd.scene.model_overrides.ModelOverride;
import rs117.hd.utils.HDUtils;
Expand Down Expand Up @@ -62,6 +63,9 @@ public class ModelStreamingManager {
@Inject
private ModelOverrideManager modelOverrideManager;

@Inject
private OcclusionManager occlusionManager;

@Inject
private FrameTimer frameTimer;

Expand Down Expand Up @@ -194,6 +198,10 @@ public void drawTemp(Projection worldProjection, Scene scene, GameObject gameObj
)) {
return;
}

final OcclusionQuery occlusionQuery = occlusionManager.obtainOcclusionQuery(ctx, gameObject.getId(), zone, orientation, false, m, x, y, z);
if(occlusionQuery != null && occlusionQuery.isOccluded())
return;
plugin.drawnTempRenderableCount++;

final boolean isModelPartiallyVisible = sceneManager.isRoot(ctx) && modelClassification == 0;
Expand Down Expand Up @@ -432,6 +440,10 @@ public void drawDynamic(
)) {
return;
}

final OcclusionQuery occlusionQuery = occlusionManager.obtainOcclusionQuery(ctx, tileObject.getHash(), zone, orient, true, m, x, y, z);
if(occlusionQuery != null && occlusionQuery.isOccluded())
return;
streamingContext.renderableCount++;

final int preOrientation = HDUtils.getModelPreOrientation(HDUtils.getObjectConfig(tileObject));
Expand Down
Loading