Skip to content

Commit 0c6796d

Browse files
committed
done with renderdoc for now
1 parent 14e0f9c commit 0c6796d

10 files changed

Lines changed: 253 additions & 9 deletions

File tree

Common/build.gradle

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ plugins {
44

55
neoForge.neoFormVersion = libs.versions.neoform.get()
66

7+
sourceSets {
8+
create("renderdoc")
9+
}
10+
711
dependencies {
812
compileOnly libs.bundles.mixin
913
compileOnly libs.jetbrains.annotations
1014
compileOnly libs.autoservice.annotations
1115

16+
implementation sourceSets.renderdoc.output
17+
1218
compileOnly libs.appdirs
1319

1420
// compileOnly libs.resourcefulconfig
@@ -21,6 +27,12 @@ dependencies {
2127

2228
testCompileOnly libs.junit.api
2329
testCompileOnly libs.neoforge.testframework
30+
31+
renderdocImplementation platform(libs.neoforge.mcdeps)
32+
renderdocCompileOnly libs.autoservice.annotations
33+
renderdocAnnotationProcessor libs.autoservice
34+
renderdocImplementation libs.slf4j.api
35+
renderdocCompileOnly libs.neoforge.fancymodloader
2436
}
2537

2638
neoForge {
@@ -50,10 +62,63 @@ configurations {
5062
canBeResolved = false
5163
canBeConsumed = true
5264
}
65+
66+
renderdoc {
67+
canBeResolved = false
68+
canBeConsumed = true
69+
}
5370
}
5471

72+
processRenderdocResources {
73+
filteringCharset = "UTF-8"
74+
75+
def expandProps = [
76+
"version" : version,
77+
"maven_group_id" : maven_group_id,
78+
"mod_id" : mod_id,
79+
"mod_display_name" : mod_display_name,
80+
"mod_description" : mod_description,
81+
"sources_url" : sources_url,
82+
"issues_url" : issues_url,
83+
"license_url" : license_url,
84+
"discord_url" : discord_url,
85+
"homepage_url" : homepage_url,
86+
"curseforge_id" : curseforge_id,
87+
"modrinth_id" : modrinth_id,
88+
89+
"minecraft_version" : libs.versions.minecraft.get(),
90+
"neoforge_version" : libs.versions.neoforge.get(),
91+
"fabric_loader_version": libs.versions.fabric.loader.get()
92+
]
93+
94+
filesMatching(['*.mod.json', 'META-INF/neoforge.mods.toml', '*.mixins.json']) {
95+
expand expandProps
96+
}
97+
inputs.properties(expandProps)
98+
}
99+
100+
tasks.register("renderdocJar", Jar) {
101+
archiveClassifier.set("renderdoc-loader")
102+
from sourceSets.renderdoc.output
103+
104+
manifest {
105+
attributes([
106+
'Specification-Title' : rootProject.name,
107+
'Specification-Version' : project.version,
108+
'Implementation-Title' : "${rootProject.name}-${project.name}-renderdoc-loader",
109+
'Maven-Artifact' : "${maven_group_id}:${rootProject.name}-${project.name}:${project.version}:renderdoc-loader",
110+
'Implementation-Version' : project.version,
111+
'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})",
112+
'Built-On-Minecraft' : libs.versions.minecraft.get()
113+
])
114+
}
115+
}
116+
tasks.assemble.dependsOn(tasks.renderdocJar)
117+
55118
artifacts {
56119
testmod(sourceSets.testmod.output.classesDirs.singleFile) {
57120
builtBy testmodClasses
58121
}
122+
123+
add("renderdoc", tasks.renderdocJar)
59124
}

Common/src/main/java/dev/upcraft/sparkweave/api/SparkweaveApi.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import dev.upcraft.sparkweave.SparkweaveMod;
44
import dev.upcraft.sparkweave.api.platform.Env;
55
import dev.upcraft.sparkweave.api.platform.Services;
6-
import dev.upcraft.sparkweave.client.render.RenderDocHelper;
6+
import dev.upcraft.sparkweave.renderdoc.client.RenderDocHelper;
77
import org.apache.logging.log4j.Level;
88

99
public class SparkweaveApi {
@@ -22,8 +22,10 @@ public class SparkweaveApi {
2222

2323
public static class Client {
2424

25-
// sparkweave.debug.render.load_renderdoc
26-
public static final boolean LOAD_RENDERDOC = RenderDocHelper.LOAD_RENDERDOC;
25+
/**
26+
* @see RenderDocHelper
27+
*/
28+
public static final boolean LOAD_RENDERDOC = Env.getBool("debug.render.load_renderdoc", SparkweaveMod.MODID);
2729

2830
public static final boolean LOG_MISSING_TRANSLATIONS = DEVELOPMENT_ENVIRONMENT || Env.getBool("debug.log.missing_translations", SparkweaveMod.MODID);
2931

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dev.upcraft.sparkweave.neoforge.client.renderdoc;
2+
3+
import com.google.auto.service.AutoService;
4+
import dev.upcraft.sparkweave.renderdoc.client.RenderDocHelper;
5+
import net.neoforged.neoforgespi.earlywindow.GraphicsBootstrapper;
6+
7+
/**
8+
* RenderDoc needs to be loaded before NeoForge initializes their graphics context, so we need to do it via a
9+
* {@linkplain GraphicsBootstrapper}. However, those must be loaded as a service, from a separate non-mod jar,
10+
* top-level from the mods directory. Therefore we first extract the jar and then tell the user to relaunch the game.
11+
*/
12+
@AutoService(GraphicsBootstrapper.class)
13+
public class SparkweaveRenderdocLoader implements GraphicsBootstrapper {
14+
15+
@Override
16+
public String name() {
17+
return "Sparkweave Engine/RenderdocLoader";
18+
}
19+
20+
@Override
21+
public void bootstrap(String[] arguments) {
22+
RenderDocHelper.init();
23+
}
24+
}

Common/src/main/java/dev/upcraft/sparkweave/client/render/RenderDocHelper.java renamed to Common/src/renderdoc/java/dev/upcraft/sparkweave/renderdoc/client/RenderDocHelper.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
package dev.upcraft.sparkweave.client.render;
1+
package dev.upcraft.sparkweave.renderdoc.client;
22

33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
55

66
import java.io.File;
77
import java.nio.file.Files;
88
import java.nio.file.Path;
9+
import java.util.concurrent.atomic.AtomicBoolean;
910

1011
public class RenderDocHelper {
1112

12-
private static final Logger LOGGER = LoggerFactory.getLogger(RenderDocHelper.class);
1313
public static final boolean LOAD_RENDERDOC = Boolean.getBoolean("sparkweave.debug.render.load_renderdoc");
14+
private static final AtomicBoolean INITIALIZED = new AtomicBoolean(false);
15+
private static final Logger LOGGER = LoggerFactory.getLogger(RenderDocHelper.class);
1416

15-
public static void init() {
16-
if(LOAD_RENDERDOC) {
17+
public static synchronized void init() {
18+
if(LOAD_RENDERDOC && !isLoaded()) {
1719
LOGGER.info("Loading RenderDoc");
1820
var libraryPath = System.getProperty("java.library.path");
1921

@@ -44,6 +46,13 @@ public static void init() {
4446
if(!loaded) {
4547
LOGGER.warn("RenderDoc not found or unable to load");
4648
}
49+
else {
50+
INITIALIZED.set(true);
51+
}
4752
}
4853
}
54+
55+
public static boolean isLoaded() {
56+
return INITIALIZED.get();
57+
}
4958
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"schemaVersion": 1,
3+
"id": "${mod_id}_renderdoc_loader",
4+
"version": "${version}",
5+
"name": "${mod_display_name} RenderDoc Loader",
6+
"license": "${license_url}",
7+
"icon": "icon.png",
8+
"custom": {
9+
"modmenu": {
10+
"badges": [
11+
"library"
12+
],
13+
"parent": "${mod_id}",
14+
"update_checker": false
15+
}
16+
},
17+
"depends": {
18+
"${mod_id}": "=${version}"
19+
},
20+
"environment": "client"
21+
}

Fabric/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ dependencies {
1717
modImplementation libs.fabric.loader
1818
modImplementation libs.fabric.api
1919

20+
implementation project(path: ":Common", configuration: "renderdoc")
21+
include(project(path: ":Common", configuration: "renderdoc"))
22+
2023
testmodImplementation sourceSets.main.output
2124
testmodCompileOnly project(path: ":Common", configuration: "testmod")
2225
testmodCompileOnly libs.autoservice.annotations

Fabric/src/main/java/dev/upcraft/sparkweave/fabric/mixin/client/MainMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dev.upcraft.sparkweave.fabric.mixin.client;
22

3-
import dev.upcraft.sparkweave.client.render.RenderDocHelper;
3+
import dev.upcraft.sparkweave.renderdoc.client.RenderDocHelper;
44
import net.minecraft.client.main.Main;
55
import org.spongepowered.asm.mixin.Mixin;
66
import org.spongepowered.asm.mixin.injection.At;

NeoForge/build.gradle

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ dependencies {
1616
compileOnly libs.autoservice.annotations
1717
annotationProcessor libs.autoservice
1818

19+
implementation project(path: ":Common", configuration: "renderdoc")
20+
// additionalRuntimeClasspath project(path: ":Common", configuration: "renderdoc")
21+
1922
testmodImplementation sourceSets.main.output
2023
testmodCompileOnly project(path: ":Common", configuration: "testmod")
2124
testmodCompileOnly libs.autoservice.annotations
@@ -40,6 +43,14 @@ dependencies {
4043
testRuntimeOnly libs.junit.engine
4144
}
4245

46+
jar {
47+
def loaderJarName = "${mod_id}-renderdoc-loader-${version}.jar"
48+
from(project(":Common").tasks.renderdocJar) {
49+
into "META-INF/jarjar"
50+
rename { loaderJarName }
51+
}
52+
}
53+
4354
test {
4455
useJUnitPlatform()
4556
}
@@ -60,6 +71,10 @@ neoForge {
6071
sourceSet(project(":Common").sourceSets.main)
6172
}
6273

74+
"${mod_id}_renderdoc_loader" {
75+
sourceSet(project(":Common").sourceSets.renderdoc)
76+
}
77+
6378
"${project.mod_id}_testmod" {
6479
sourceSet(sourceSets.testmod)
6580
sourceSet(project(":Common").sourceSets.testmod)
@@ -102,7 +117,7 @@ neoForge {
102117
systemProperty "${project.mod_id}.debug.render.load_renderdoc", 'true'
103118

104119
sourceSet = sourceSets.main
105-
loadedMods.set([mods."${mod_id}"])
120+
loadedMods.set([mods."${mod_id}", mods."${mod_id}_renderdoc_loader"])
106121
}
107122

108123
server {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package dev.upcraft.sparkweave.neoforge.impl.client;
2+
3+
import dev.upcraft.sparkweave.SparkweaveMod;
4+
import dev.upcraft.sparkweave.api.logging.SparkweaveLoggerFactory;
5+
import net.neoforged.api.distmarker.Dist;
6+
import net.neoforged.bus.api.IEventBus;
7+
import net.neoforged.fml.ModContainer;
8+
import net.neoforged.fml.ModLoader;
9+
import net.neoforged.fml.ModLoadingIssue;
10+
import net.neoforged.fml.common.Mod;
11+
import net.neoforged.fml.loading.FMLPaths;
12+
import net.neoforged.fml.loading.progress.StartupNotificationManager;
13+
import org.apache.logging.log4j.Logger;
14+
15+
import javax.annotation.Nullable;
16+
import java.io.FileNotFoundException;
17+
import java.io.IOException;
18+
import java.lang.invoke.MethodHandles;
19+
import java.lang.invoke.MethodType;
20+
import java.nio.file.Files;
21+
import java.nio.file.StandardCopyOption;
22+
import java.util.List;
23+
import java.util.jar.Attributes;
24+
import java.util.jar.JarInputStream;
25+
26+
@Mod(value = SparkweaveMod.MODID, dist = Dist.CLIENT)
27+
public class LaunchBootstrap {
28+
29+
private static final Logger LOGGER = SparkweaveLoggerFactory.getLogger();
30+
31+
private static final Boolean LOAD_RENDERDOC = Boolean.getBoolean("sparkweave.debug.render.load_renderdoc");
32+
33+
public LaunchBootstrap(ModContainer modContainer, IEventBus modBus) throws IOException {
34+
var currentModVersion = modContainer.getModInfo().getVersion().toString();
35+
if(LOAD_RENDERDOC) {
36+
var pb = StartupNotificationManager.prependProgressBar("Extracting RenderDoc", 2);
37+
38+
var helperClass = getClass("dev.upcraft.sparkweave.renderdoc.client.RenderDocHelper");
39+
if(helperClass != null) {
40+
try {
41+
var isLoadedMethod = MethodHandles.publicLookup().findStatic(helperClass, "isLoaded", MethodType.methodType(boolean.class));
42+
if((boolean) isLoadedMethod.invokeExact()) {
43+
LOGGER.info("RenderDoc already loaded, skipping jar extraction!");
44+
pb.complete();
45+
return;
46+
}
47+
} catch (Throwable e) {
48+
throw new RuntimeException("Reflection error trying to check RenderDocHelper API", e);
49+
}
50+
}
51+
52+
LOGGER.debug("Locating RenderDoc loader Jar file...");
53+
var modsDir = FMLPaths.MODSDIR.get();
54+
var jarName = "%s-renderdoc-loader.jar".formatted(SparkweaveMod.MODID);
55+
var jarFile = modsDir.resolve(jarName);
56+
if(Files.exists(jarFile)) {
57+
try(var stream = new JarInputStream(Files.newInputStream(jarFile))) {
58+
var foundVersion = stream.getManifest().getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
59+
LOGGER.debug("Found existing loader file, version {}", foundVersion);
60+
if(foundVersion.equals(currentModVersion)) {
61+
LOGGER.info("Version matches, continuing launch!");
62+
pb.complete();
63+
return;
64+
}
65+
}
66+
}
67+
pb.increment();
68+
69+
var internalJarName = "META-INF/jarjar/%s-renderdoc-loader-%s.jar".formatted(SparkweaveMod.MODID, currentModVersion);
70+
var internalJarFile = modContainer.getModInfo().getOwningFile().getFile().findResource(internalJarName);
71+
if(!Files.exists(internalJarFile)) {
72+
throw new FileNotFoundException("Unable to find %s in mod resources!".formatted(internalJarName));
73+
}
74+
LOGGER.debug("Extracting new file...");
75+
Files.copy(internalJarFile, jarFile, StandardCopyOption.REPLACE_EXISTING);
76+
pb.increment();
77+
78+
pb.label("RenderDoc loader file extracted.");
79+
// TODO make translatable once NEO fixes this issue
80+
//noinspection UnstableApiUsage
81+
ModLoader.addLoadingIssue(new ModLoadingIssue(ModLoadingIssue.Severity.ERROR, "RenderDoc loader successfully extracted, please restart your game!", List.of()));
82+
83+
StartupNotificationManager.addModMessage("Successfully extracted RenderDoc loader, waiting for restart.");
84+
pb.complete();
85+
86+
// throw new ModLoadingException(new ModLoadingIssue(ModLoadingIssue.Severity.ERROR, "RenderDoc loader successfully extracted, please restart your game!", List.of()));
87+
}
88+
}
89+
90+
@SuppressWarnings("unchecked")
91+
@Nullable
92+
private static <T> Class<T> getClass(String name) {
93+
try {
94+
return (Class<T>) Class.forName(name);
95+
} catch (ClassNotFoundException e) {
96+
return null;
97+
}
98+
}
99+
}

gradle/libs.versions.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ neoform = "1.21.1-20240808.144430"
1313
# NeoForge
1414
# https://projects.neoforged.net/neoforged/neoforge
1515
neoforge = "21.1.148"
16+
# https://projects.neoforged.net/neoforged/fancymodloader
17+
# MUST match the version that neoforge uses! https://github.com/neoforged/NeoForge/blob/1.21.1/gradle.properties
18+
fancymodloader = "4.0.39"
1619

1720
# Fabric
1821
# https://fabricmc.net/develop
@@ -41,6 +44,8 @@ resourcefulconfig = "3.0.9"
4144
[libraries]
4245
# NeoForge
4346
neoforge_testframework = { module = "net.neoforged:testframework", version.ref = "neoforge" }
47+
neoforge_mcdeps = { module = "net.neoforged:minecraft-dependencies", version.ref = "minecraft" }
48+
neoforge_fancymodloader = { module = "net.neoforged.fancymodloader:loader", version.ref = "fancymodloader" }
4449

4550
# Fabric
4651
fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" }
@@ -64,6 +69,7 @@ autoservice_annotations = { module = "com.google.auto.service:auto-service-annot
6469
junit_api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
6570
junit_launcher = { module = "org.junit.platform:junit-platform-launcher" }
6671
junit_engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
72+
slf4j_api = { module = "org.slf4j:slf4j-api" }
6773

6874
# Mods
6975
emi = { module = "dev.emi:emi-xplat-mojmap", version.ref = "emi" }

0 commit comments

Comments
 (0)