mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-26 14:24:30 +00:00
Tracy 0.14 (#2019)
This commit is contained in:
1 parent
bf9492dffb
commit
bc8116006c
21 files changed
+540
-80
No files matched your search
@@ -2,7 +2,8 @@
|
||||
# Builds the libTracyClient shared library for the tracy-client module.
|
||||
set -euo pipefail
|
||||
|
||||
TRACY_VERSION="${TRACY_VERSION:-v0.13.1}"
|
||||
TRACY_VERSION="${TRACY_VERSION:-v0.14.0}"
|
||||
TRACY_VERSION_BARE="${TRACY_VERSION#v}"
|
||||
OUT_DIR="${OUT_DIR:-dist/tracy-natives}"
|
||||
TRACY_REPO="https://github.com/wolfpld/tracy"
|
||||
|
||||
@@ -16,7 +17,7 @@ case "$(uname -m)" in
|
||||
arm64|aarch64) PLAT_ARCH="arm64" ;;
|
||||
*) PLAT_ARCH="x64" ;;
|
||||
esac
|
||||
RES_DIR="${RES_DIR:-$REPO_ROOT/tracy-client/src/main/resources/natives/tracy/$PLAT_OS-$PLAT_ARCH}"
|
||||
RES_DIR="${RES_DIR:-$REPO_ROOT/tracy-client/src/main/resources/natives/tracy/$TRACY_VERSION_BARE/$PLAT_OS-$PLAT_ARCH}"
|
||||
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORK_DIR"' EXIT
|
||||
@@ -33,7 +34,8 @@ fi
|
||||
BUILD_DIR="$WORK_DIR/build"
|
||||
export MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-11.0}"
|
||||
|
||||
cmake -S "$SRC_DIR" -B "$BUILD_DIR" \
|
||||
cmake -S "$REPO_ROOT/tracy-client/src/main/native" -B "$BUILD_DIR" \
|
||||
-DTRACY_SRC_DIR="$SRC_DIR" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DTRACY_STATIC=OFF \
|
||||
|
||||
@@ -6,10 +6,6 @@ on:
|
||||
- "tracy-v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tracy-version:
|
||||
description: Tracy git tag to build
|
||||
required: false
|
||||
default: v0.13.1
|
||||
publish:
|
||||
description: Publish angelica-tracy.jar to the GTNH maven
|
||||
type: boolean
|
||||
@@ -20,25 +16,25 @@ jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [linux-x64, windows-x64, macos-x64, macos-arm64]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
platform: linux-x64
|
||||
- os: windows-2025
|
||||
platform: windows-x64
|
||||
- os: macos-15-intel
|
||||
platform: macos-x64
|
||||
- os: macos-15
|
||||
platform: macos-arm64
|
||||
- platform: linux-x64
|
||||
os: ubuntu-22.04
|
||||
- platform: windows-x64
|
||||
os: windows-2025
|
||||
- platform: macos-x64
|
||||
os: macos-15-intel
|
||||
- platform: macos-arm64
|
||||
os: macos-15
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Build libTracyClient
|
||||
shell: bash
|
||||
env:
|
||||
RAW_VERSION: ${{ github.ref_type == 'tag' && github.ref_name || inputs.tracy-version }}
|
||||
OUT_DIR: dist/tracy-natives
|
||||
run: |
|
||||
export TRACY_VERSION="${RAW_VERSION#tracy-}"
|
||||
export TRACY_VERSION="v$(sed -nE 's/^tracy = "(.*)"$/\1/p' gradle/libs.versions.toml)"
|
||||
bash .github/scripts/build-tracy-natives.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -56,14 +52,6 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
- name: Check tracy version matches the version catalog
|
||||
shell: bash
|
||||
env:
|
||||
RAW_VERSION: ${{ github.ref_type == 'tag' && github.ref_name || inputs.tracy-version }}
|
||||
run: |
|
||||
ver="${RAW_VERSION#tracy-}"
|
||||
grep -q "^tracy = \"${ver#v}\"$" gradle/libs.versions.toml \
|
||||
|| { echo "libs.versions.toml tracy does not match $ver" >&2; exit 1; }
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: tracy-natives-*
|
||||
@@ -71,8 +59,9 @@ jobs:
|
||||
- name: Stage natives into tracy-client resources
|
||||
shell: bash
|
||||
run: |
|
||||
version="$(sed -nE 's/^tracy = "(.*)"$/\1/p' gradle/libs.versions.toml)"
|
||||
for d in staging/tracy-natives-*; do
|
||||
dest="tracy-client/src/main/resources/natives/tracy/${d#staging/tracy-natives-}"
|
||||
dest="tracy-client/src/main/resources/natives/tracy/$version/${d#staging/tracy-natives-}"
|
||||
mkdir -p "$dest"
|
||||
cp "$d"/* "$dest/"
|
||||
done
|
||||
|
||||
@@ -43,3 +43,5 @@ tracy-client/src/main/resources/natives/
|
||||
tracy-client/angelica/
|
||||
dist/tracy-natives/
|
||||
*.tracy
|
||||
|
||||
tracy-client/angelica/
|
||||
@@ -52,8 +52,8 @@ configurations.configureEach {
|
||||
}
|
||||
|
||||
DependencyHandlerScope.of(dependencies).apply {
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.7.166:dev")
|
||||
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Hodgepodge:2.7.166:dev")
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.7.187:dev")
|
||||
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Hodgepodge:2.7.187:dev")
|
||||
|
||||
runtimeOnlyNonPublishable(rfg.deobf("curse.maven:biomes-o-plenty-220318:2499612"))
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.gtnewhorizons.angelica.glsm.profiling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class SectionRegistry {
|
||||
|
||||
public interface Emitter {
|
||||
long enter(int category, String text);
|
||||
void leave(long nativeId);
|
||||
void setup(int category, String name);
|
||||
boolean isConnected();
|
||||
}
|
||||
|
||||
private static final class Category {
|
||||
final int id;
|
||||
final String name;
|
||||
|
||||
Category(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Section {
|
||||
final long token;
|
||||
final int category;
|
||||
final String text;
|
||||
long nativeId;
|
||||
|
||||
Section(long token, int category, String text, long nativeId) {
|
||||
this.token = token;
|
||||
this.category = category;
|
||||
this.text = text;
|
||||
this.nativeId = nativeId;
|
||||
}
|
||||
}
|
||||
|
||||
private final Emitter emitter;
|
||||
private final List<Category> categories = new ArrayList<>();
|
||||
private final List<Section> open = new ArrayList<>();
|
||||
private long nextToken;
|
||||
private boolean connected;
|
||||
|
||||
public SectionRegistry(Emitter emitter) {
|
||||
this.emitter = emitter;
|
||||
}
|
||||
|
||||
public synchronized void registerCategory(int category, String name) {
|
||||
categories.add(new Category(category, name));
|
||||
}
|
||||
|
||||
public synchronized long enter(int category, String text) {
|
||||
syncConnection();
|
||||
final long token = ++nextToken;
|
||||
open.add(new Section(token, category, text, emitter.enter(category, text)));
|
||||
return token;
|
||||
}
|
||||
|
||||
public synchronized void leave(long token) {
|
||||
for (int i = 0; i < open.size(); i++) {
|
||||
final Section section = open.get(i);
|
||||
if (section.token == token) {
|
||||
open.remove(i);
|
||||
if (section.nativeId != 0L) emitter.leave(section.nativeId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void poll() {
|
||||
syncConnection();
|
||||
}
|
||||
|
||||
private void syncConnection() {
|
||||
final boolean now = emitter.isConnected();
|
||||
if (now == connected) return;
|
||||
connected = now;
|
||||
if (now) replay();
|
||||
}
|
||||
|
||||
private void replay() {
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
final Category category = categories.get(i);
|
||||
emitter.setup(category.id, category.name);
|
||||
}
|
||||
for (int i = 0; i < open.size(); i++) {
|
||||
final Section section = open.get(i);
|
||||
section.nativeId = emitter.enter(section.category, section.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,18 @@ public final class Tracy {
|
||||
public static final int COLOR_IRIS = 0x9E862E; // gold
|
||||
public static final int COLOR_FFP = 0x7A4E9E; // purple
|
||||
|
||||
public static final int SECTION_WORLD = 1;
|
||||
public static final int SECTION_SHADERS = 2;
|
||||
public static final int SECTION_BENCHMARK = 3;
|
||||
public static final int SECTION_UI = 4;
|
||||
|
||||
private static final SectionRegistry SECTIONS = new SectionRegistry(new SectionRegistry.Emitter() {
|
||||
@Override public long enter(int category, String text) { return BACKEND.sectionEnter(category, text); }
|
||||
@Override public void leave(long nativeId) { BACKEND.sectionLeave(nativeId); }
|
||||
@Override public void setup(int category, String name) { BACKEND.sectionSetup(category, name); }
|
||||
@Override public boolean isConnected() { return BACKEND.isConnected(); }
|
||||
});
|
||||
|
||||
private static final ThreadLocal<ZoneStack> STACK = new ThreadLocal<>() {
|
||||
@Override
|
||||
protected ZoneStack initialValue() {
|
||||
@@ -62,6 +74,10 @@ public final class Tracy {
|
||||
FINE_ZONES = ENABLED && SystemProperties.TRACY_FINE_ZONES;
|
||||
if (ENABLED) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Tracy::shutdown, "Tracy-Shutdown"));
|
||||
SECTIONS.registerCategory(SECTION_WORLD, "World");
|
||||
SECTIONS.registerCategory(SECTION_SHADERS, "Shaders");
|
||||
SECTIONS.registerCategory(SECTION_BENCHMARK, "Benchmark");
|
||||
SECTIONS.registerCategory(SECTION_UI, "UI");
|
||||
LOGGER.info("Tracy profiling enabled");
|
||||
}
|
||||
}
|
||||
@@ -168,7 +184,7 @@ public final class Tracy {
|
||||
final String name = stack.poppedName();
|
||||
if (name != null && WARNED_LEAKS.add(name)) {
|
||||
LOGGER.warn("Tracy: unbalanced profiler section '{}' left open (leaked by its caller); closed at next root", name);
|
||||
BACKEND.message("unbalanced profiler section '" + name + "' closed at root");
|
||||
BACKEND.message("unbalanced profiler section '" + name + "' closed at root", TracyBackend.SEVERITY_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,6 +290,7 @@ public final class Tracy {
|
||||
threadNameRefreshed = true;
|
||||
BACKEND.setCurrentThreadName(Thread.currentThread().getName());
|
||||
}
|
||||
SECTIONS.poll();
|
||||
BACKEND.frameMark();
|
||||
}
|
||||
|
||||
@@ -330,8 +347,22 @@ public final class Tracy {
|
||||
}
|
||||
|
||||
public static void message(String text) {
|
||||
message(text, TracyBackend.SEVERITY_INFO);
|
||||
}
|
||||
|
||||
public static void message(String text, int severity) {
|
||||
if (!ENABLED || SHUTTING_DOWN || !CaptureGate.markersThisFrame) return;
|
||||
BACKEND.message(text);
|
||||
BACKEND.message(text, severity);
|
||||
}
|
||||
|
||||
public static long sectionEnter(int category, String text) {
|
||||
if (!ENABLED || SHUTTING_DOWN) return 0L;
|
||||
return SECTIONS.enter(category, text);
|
||||
}
|
||||
|
||||
public static void sectionLeave(long token) {
|
||||
if (token == 0L || !ENABLED || SHUTTING_DOWN) return;
|
||||
SECTIONS.leave(token);
|
||||
}
|
||||
|
||||
public static boolean isConnected() {
|
||||
|
||||
@@ -5,6 +5,13 @@ public interface TracyBackend {
|
||||
int PLOT_FORMAT_MEMORY = 1;
|
||||
int PLOT_FORMAT_PERCENTAGE = 2;
|
||||
|
||||
int SEVERITY_TRACE = 0;
|
||||
int SEVERITY_DEBUG = 1;
|
||||
int SEVERITY_INFO = 2;
|
||||
int SEVERITY_WARNING = 3;
|
||||
int SEVERITY_ERROR = 4;
|
||||
int SEVERITY_FATAL = 5;
|
||||
|
||||
boolean init();
|
||||
|
||||
long internSrcLoc(String name, int color);
|
||||
@@ -24,7 +31,14 @@ public interface TracyBackend {
|
||||
|
||||
void plotInt(long namePtr, long value);
|
||||
void plot(long namePtr, double value);
|
||||
void message(String text);
|
||||
|
||||
void message(String text, int severity);
|
||||
default void message(String text) { message(text, SEVERITY_INFO); }
|
||||
|
||||
long sectionEnter(int category, String text);
|
||||
void sectionLeave(long id);
|
||||
void sectionSetup(int category, String name);
|
||||
|
||||
void setCurrentThreadName(String name);
|
||||
boolean isConnected();
|
||||
void shutdown();
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.gtnewhorizons.angelica.glsm.profiling;
|
||||
|
||||
public final class ZoneStack {
|
||||
public static final long EMPTY = -1L;
|
||||
static final int MAX_DEPTH = 512;
|
||||
public static final int MAX_DEPTH = 512;
|
||||
|
||||
private long[] stack = new long[64];
|
||||
private boolean[] gpu = new boolean[64];
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.gtnewhorizons.angelica.glsm.profiling;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SectionRegistryTest {
|
||||
|
||||
private static final class RecordingEmitter implements SectionRegistry.Emitter {
|
||||
final List<String> setups = new ArrayList<>();
|
||||
final List<String> enters = new ArrayList<>();
|
||||
final List<Long> leaves = new ArrayList<>();
|
||||
long nextId;
|
||||
boolean connected;
|
||||
|
||||
@Override
|
||||
public long enter(int category, String text) {
|
||||
enters.add(category + ":" + text);
|
||||
return connected ? ++nextId : 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(long nativeId) {
|
||||
leaves.add(nativeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(int category, String name) {
|
||||
setups.add(category + ":" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return connected;
|
||||
}
|
||||
}
|
||||
|
||||
private final RecordingEmitter emitter = new RecordingEmitter();
|
||||
private final SectionRegistry registry = new SectionRegistry(emitter);
|
||||
|
||||
private void reconnect() {
|
||||
emitter.connected = false;
|
||||
registry.poll();
|
||||
emitter.connected = true;
|
||||
registry.poll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void tokensOutliveEveryReplayAndLeaveUsesTheNewestId() {
|
||||
final long openedWhileDisconnected = registry.enter(1, "world");
|
||||
assertNotEquals(0L, openedWhileDisconnected, "token must be valid while disconnected");
|
||||
assertEquals(0L, emitter.nextId, "no native id while disconnected");
|
||||
|
||||
emitter.connected = true;
|
||||
registry.poll();
|
||||
final long openedWhileConnected = registry.enter(2, "shaders");
|
||||
assertNotEquals(openedWhileDisconnected, openedWhileConnected);
|
||||
|
||||
reconnect();
|
||||
emitter.leaves.clear();
|
||||
registry.leave(openedWhileDisconnected);
|
||||
registry.leave(openedWhileConnected);
|
||||
|
||||
assertEquals(List.of(3L, 4L), emitter.leaves, "leave must use the post-reconnect ids");
|
||||
}
|
||||
|
||||
@Test
|
||||
void aSectionEnteredOnTheConnectingFrameIsNotEnteredTwice() {
|
||||
emitter.connected = true;
|
||||
registry.enter(2, "shaders pack / Overworld");
|
||||
registry.poll();
|
||||
|
||||
assertEquals(List.of("2:shaders pack / Overworld"), emitter.enters, "must not re-enter a section already live on this connection");
|
||||
}
|
||||
|
||||
@Test
|
||||
void reconnectReplaysEveryCategoryAndEveryOpenSection() {
|
||||
registry.registerCategory(1, "World");
|
||||
registry.registerCategory(4, "UI");
|
||||
emitter.connected = true;
|
||||
registry.poll();
|
||||
registry.enter(1, "world");
|
||||
registry.enter(4, "pause");
|
||||
emitter.setups.clear();
|
||||
emitter.enters.clear();
|
||||
|
||||
reconnect();
|
||||
|
||||
assertEquals(List.of("1:World", "4:UI"), emitter.setups, "all categories re-registered");
|
||||
assertEquals(List.of("1:world", "4:pause"), emitter.enters, "all open sections re-entered");
|
||||
}
|
||||
|
||||
@Test
|
||||
void leftSectionsAreNotResurrectedByAReconnect() {
|
||||
emitter.connected = true;
|
||||
registry.poll();
|
||||
final long token = registry.enter(1, "transient");
|
||||
registry.leave(token);
|
||||
emitter.enters.clear();
|
||||
emitter.leaves.clear();
|
||||
|
||||
reconnect();
|
||||
registry.leave(token);
|
||||
|
||||
assertTrue(emitter.enters.isEmpty(), "closed sections must not be re-entered");
|
||||
assertTrue(emitter.leaves.isEmpty(), "closed tokens must not be left twice");
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ eventbus = "7.0-beta.15"
|
||||
glslTransformLib = "0.2.0-33.g3ec381e"
|
||||
antlr4Runtime = "4.13.2"
|
||||
jcpp = "1.4.14"
|
||||
tracy = "0.13.1"
|
||||
tracy = "0.14.0"
|
||||
retroFuturaBootstrap = "1.1.0"
|
||||
|
||||
lombok = "1.18.46"
|
||||
|
||||
@@ -57,6 +57,10 @@ public final class FlybyRunner {
|
||||
private long plotTurning;
|
||||
private int lastPhase = -1;
|
||||
|
||||
private long warmupSection;
|
||||
private long runSection;
|
||||
private long legSection;
|
||||
|
||||
private long[] frameTimesNs = NO_FRAMES;
|
||||
private int frameCount;
|
||||
private boolean framesTruncated;
|
||||
@@ -180,9 +184,13 @@ public final class FlybyRunner {
|
||||
this.buildPath();
|
||||
this.freezeTimeAndWeather(mc);
|
||||
|
||||
this.state = this.warmupTicks > 0 ? State.WARMUP : State.RUNNING;
|
||||
this.tick = 0;
|
||||
if (this.state == State.RUNNING) this.beginMeasuring();
|
||||
if (this.warmupTicks > 0) {
|
||||
this.state = State.WARMUP;
|
||||
this.warmupSection = Tracy.sectionEnter(Tracy.SECTION_BENCHMARK, "flyby warmup");
|
||||
} else {
|
||||
this.beginMeasuring();
|
||||
}
|
||||
|
||||
LOGGER.info("Flyby {} starting at {} {} {} yaw {}", this.route.id(),
|
||||
this.originX, this.originY, this.originZ, this.originYaw);
|
||||
@@ -252,12 +260,18 @@ public final class FlybyRunner {
|
||||
final int phase = (leg << 1) | turning;
|
||||
if (phase != this.lastPhase) {
|
||||
this.lastPhase = phase;
|
||||
Tracy.message("flyby " + (turning != 0 ? "turn" : "leg") + " " + leg);
|
||||
final String label = "flyby " + (turning != 0 ? "turn" : "leg") + " " + leg;
|
||||
Tracy.message(label);
|
||||
Tracy.sectionLeave(this.legSection);
|
||||
this.legSection = Tracy.sectionEnter(Tracy.SECTION_BENCHMARK, label);
|
||||
}
|
||||
}
|
||||
|
||||
private void beginMeasuring() {
|
||||
this.state = State.RUNNING;
|
||||
Tracy.sectionLeave(this.warmupSection);
|
||||
this.warmupSection = 0L;
|
||||
if (Tracy.ENABLED) this.runSection = Tracy.sectionEnter(Tracy.SECTION_BENCHMARK, "flyby " + this.route.id());
|
||||
this.plotLeg = Tracy.plotHandle("flyby.leg");
|
||||
this.plotTurning = Tracy.plotHandle("flyby.turning");
|
||||
this.lastPhase = -1;
|
||||
@@ -265,11 +279,9 @@ public final class FlybyRunner {
|
||||
this.frameCount = 0;
|
||||
this.lastFrameNs = 0L;
|
||||
this.runStartNs = System.nanoTime();
|
||||
Tracy.message("flyby start route=" + this.route.id()
|
||||
+ " length=" + this.runLength + this.route.lengthUnit()
|
||||
+ " speed=" + this.route.speedOr(this.speed) + "b/t"
|
||||
+ " ticks=" + this.runTicks
|
||||
+ " sdlgpu=" + SystemProperties.USE_SDL_GPU);
|
||||
if (Tracy.ENABLED) {
|
||||
Tracy.message("flyby start route=" + this.route.id() + " length=" + this.runLength + this.route.lengthUnit() + " speed=" + this.route.speedOr(this.speed) + "b/t ticks=" + this.runTicks + " sdlgpu=" + SystemProperties.USE_SDL_GPU);
|
||||
}
|
||||
}
|
||||
|
||||
private void holdPosition(EntityClientPlayerMP player) {
|
||||
@@ -364,7 +376,11 @@ public final class FlybyRunner {
|
||||
this.state = State.SETTLE;
|
||||
this.tick = 0;
|
||||
final long elapsedNs = System.nanoTime() - this.runStartNs;
|
||||
Tracy.message("flyby end route=" + this.route.id() + " frames=" + this.frameCount);
|
||||
Tracy.sectionLeave(this.legSection);
|
||||
this.legSection = 0L;
|
||||
Tracy.sectionLeave(this.runSection);
|
||||
this.runSection = 0L;
|
||||
if (Tracy.ENABLED) Tracy.message("flyby end route=" + this.route.id() + " frames=" + this.frameCount);
|
||||
|
||||
final String summary = this.summarise(elapsedNs, player);
|
||||
LOGGER.info(summary);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.gtnewhorizons.angelica.profiling;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiIngameMenu;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class TracyUiSections {
|
||||
|
||||
private static final Map<Class<?>, String> LABELS = new HashMap<>();
|
||||
private static Class<?> current = TracyUiSections.class;
|
||||
private static long section;
|
||||
|
||||
private TracyUiSections() {}
|
||||
|
||||
public static void poll(GuiScreen screen) {
|
||||
if (!Tracy.ENABLED) return;
|
||||
final Class<?> screenClass = screen == null ? null : screen.getClass();
|
||||
if (screenClass == current) return;
|
||||
current = screenClass;
|
||||
Tracy.sectionLeave(section);
|
||||
section = Tracy.sectionEnter(Tracy.SECTION_UI, label(screenClass));
|
||||
}
|
||||
|
||||
private static String label(Class<?> screenClass) {
|
||||
if (screenClass == null) return "in world";
|
||||
String label = LABELS.get(screenClass);
|
||||
if (label == null) {
|
||||
if (screenClass == GuiMainMenu.class) label = "main menu";
|
||||
else if (screenClass == GuiIngameMenu.class) label = "pause";
|
||||
else label = screenClass.getSimpleName();
|
||||
LABELS.put(screenClass, label);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ import com.gtnewhorizons.angelica.dynamiclights.DynamicLights;
|
||||
import com.gtnewhorizons.angelica.dynamiclights.config.EntityLightConfig;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.backend.VSyncMode;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import com.gtnewhorizons.angelica.hudcaching.HUDCaching;
|
||||
import com.gtnewhorizons.angelica.iris.IrisGLSMBridge;
|
||||
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
|
||||
@@ -216,9 +217,15 @@ public final class ClientProxy extends CommonProxy {
|
||||
}
|
||||
}
|
||||
|
||||
private long worldSection;
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldLoad(WorldEvent.Load event) {
|
||||
if (!event.world.isRemote) return;
|
||||
if (Tracy.ENABLED) {
|
||||
Tracy.sectionLeave(this.worldSection);
|
||||
this.worldSection = Tracy.sectionEnter(Tracy.SECTION_WORLD, "world " + event.world.provider.getDimensionName() + " (dim " + event.world.provider.dimensionId + ")");
|
||||
}
|
||||
if (GLStateManager.isRunningSplash()) {
|
||||
GLStateManager.setRunningSplash(false);
|
||||
LOGGER.info("World loaded - Enabling GLSM Cache");
|
||||
@@ -238,6 +245,8 @@ public final class ClientProxy extends CommonProxy {
|
||||
@SubscribeEvent
|
||||
public void onWorldUnload(WorldEvent.Unload event) {
|
||||
if (!event.world.isRemote) return;
|
||||
Tracy.sectionLeave(this.worldSection);
|
||||
this.worldSection = 0L;
|
||||
DynamicLights.get().removeAllLightSources();
|
||||
GpuCulling.onWorldUnload();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.coderbot.iris.pipeline;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.uniforms.SystemTimeUniforms;
|
||||
@@ -19,6 +20,7 @@ public class PipelineManager {
|
||||
private final Map<String, WorldRenderingPipeline> pipelinesPerDimension = new HashMap<>();
|
||||
private WorldRenderingPipeline pipeline = new FixedFunctionWorldRenderingPipeline();
|
||||
private String lastPreparedDimension = null;
|
||||
private long shaderSection;
|
||||
@Getter
|
||||
private int versionCounterForSodiumShaderReload = 0;
|
||||
|
||||
@@ -41,6 +43,9 @@ public class PipelineManager {
|
||||
Iris.logger.info("Creating pipeline for dimension '{}'", currentDimension);
|
||||
pipeline = pipelineFactory.apply(currentDimension);
|
||||
pipelinesPerDimension.put(currentDimension, pipeline);
|
||||
if (Tracy.ENABLED) {
|
||||
shaderSection = Tracy.sectionEnter(Tracy.SECTION_SHADERS, "shaders " + Iris.getCurrentPackName() + " / " + currentDimension);
|
||||
}
|
||||
} else {
|
||||
pipeline = pipelinesPerDimension.get(currentDimension);
|
||||
}
|
||||
@@ -70,6 +75,8 @@ public class PipelineManager {
|
||||
* @see <a href="https://github.com/IrisShaders/Iris/issues/1330">this GitHub issue</a>
|
||||
*/
|
||||
public void destroyPipeline() {
|
||||
Tracy.sectionLeave(shaderSection);
|
||||
shaderSection = 0L;
|
||||
pipelinesPerDimension.forEach((dimensionName, pipeline) -> {
|
||||
Iris.logger.info("Destroying pipeline for dimension '{}'", dimensionName);
|
||||
resetTextureState();
|
||||
|
||||
+2
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.tracy;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.Tracy;
|
||||
import com.gtnewhorizons.angelica.profiling.GpuFrameLagMeter;
|
||||
import com.gtnewhorizons.angelica.profiling.TracyFramePlots;
|
||||
import com.gtnewhorizons.angelica.profiling.TracyUiSections;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -20,6 +21,7 @@ public class MixinMinecraft_Tracy {
|
||||
TracyFramePlots.onFrame((Minecraft) (Object) this);
|
||||
GpuFrameLagMeter.onFrame();
|
||||
Tracy.frameMark();
|
||||
TracyUiSections.poll(((Minecraft) (Object) this).currentScreen);
|
||||
Tracy.gpuCollect();
|
||||
}
|
||||
|
||||
|
||||
+79
-25
@@ -4,6 +4,7 @@ import com.gtnewhorizons.angelica.config.SystemProperties;
|
||||
import com.gtnewhorizons.angelica.glsm.backend.BackendManager;
|
||||
import com.gtnewhorizons.angelica.glsm.backend.RenderBackend;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.TracyBackend;
|
||||
import com.gtnewhorizons.angelica.glsm.profiling.ZoneStack;
|
||||
import me.eigenraven.lwjgl3ify.api.Lwjgl3Aware;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -18,12 +19,12 @@ import org.lwjgl.system.libffi.FFIType;
|
||||
import org.lwjgl.system.libffi.LibFFI;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.DoubleBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static org.lwjgl.system.MemoryStack.stackPush;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
import static org.lwjgl.system.MemoryUtil.memAddress;
|
||||
import static org.lwjgl.system.MemoryUtil.memGetInt;
|
||||
import static org.lwjgl.system.MemoryUtil.memPutAddress;
|
||||
import static org.lwjgl.system.MemoryUtil.memPutByte;
|
||||
import static org.lwjgl.system.MemoryUtil.memPutInt;
|
||||
@@ -33,12 +34,16 @@ import static org.lwjgl.system.MemoryUtil.nmemAllocChecked;
|
||||
public final class TracyClientBackend implements TracyBackend {
|
||||
private static final Logger LOGGER = LogManager.getLogger("Tracy");
|
||||
private static final int MAX_TEXT = 8192;
|
||||
private static final int ACTIVE_OFFSET = 4;
|
||||
|
||||
private SharedLibrary lib;
|
||||
private TracyLibrary sym;
|
||||
private SrcLocInterner interner;
|
||||
private long emptyString;
|
||||
private FFICIF plotCif;
|
||||
private int ctxSize;
|
||||
int zoneCtxSize() {
|
||||
return ctxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init() {
|
||||
@@ -52,18 +57,15 @@ public final class TracyClientBackend implements TracyBackend {
|
||||
sym = TracyLibrary.resolve(lib);
|
||||
if (sym == null) return false;
|
||||
|
||||
emptyString = nmemAllocChecked(1);
|
||||
memPutByte(emptyString, (byte) 0);
|
||||
|
||||
final PointerBuffer plotArgTypes = MemoryUtil.memAllocPointer(2);
|
||||
plotArgTypes.put(0, LibFFI.ffi_type_pointer.address()).put(1, LibFFI.ffi_type_double.address());
|
||||
plotCif = FFICIF.malloc();
|
||||
final int status = LibFFI.ffi_prep_cif(plotCif, LibFFI.FFI_DEFAULT_ABI, LibFFI.ffi_type_void, plotArgTypes);
|
||||
if (status != LibFFI.FFI_OK) {
|
||||
LOGGER.warn("Tracy: ffi_prep_cif failed: {}", status);
|
||||
ctxSize = (int) JNI.invokeJ(sym.zoneCtxSize);
|
||||
if (ctxSize <= 0 || Integer.bitCount(ctxSize) != 1) {
|
||||
LOGGER.warn("Tracy: zone context size {} is not a power of two; slot addressing would be wrong", ctxSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
emptyString = nmemAllocChecked(1);
|
||||
memPutByte(emptyString, (byte) 0);
|
||||
|
||||
interner = new SrcLocInterner(this::allocSrcLoc, SystemProperties.TRACY_MAX_SRC_LOCS);
|
||||
|
||||
JNI.invokeV(sym.startupProfiler);
|
||||
@@ -101,26 +103,64 @@ public final class TracyClientBackend implements TracyBackend {
|
||||
return interner.dynamicSrcLoc();
|
||||
}
|
||||
|
||||
private static final ConcurrentLinkedQueue<SlotArena> ARENAS = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private static final class SlotArena {
|
||||
private final long base;
|
||||
private final int strideShift;
|
||||
private int depth;
|
||||
|
||||
SlotArena(int stride) {
|
||||
this.strideShift = Integer.numberOfTrailingZeros(stride);
|
||||
this.base = nmemAllocChecked((long) stride * ZoneStack.MAX_DEPTH);
|
||||
}
|
||||
|
||||
long top() {
|
||||
return depth == ZoneStack.MAX_DEPTH ? NULL : base + ((long) depth << strideShift);
|
||||
}
|
||||
|
||||
void unwindTo(long slot) {
|
||||
final long index = (slot - base) >> strideShift;
|
||||
if (index >= 0 && index < ZoneStack.MAX_DEPTH) depth = (int) index;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<SlotArena> slots = ThreadLocal.withInitial(() -> {
|
||||
final SlotArena arena = new SlotArena(ctxSize);
|
||||
ARENAS.add(arena);
|
||||
return arena;
|
||||
});
|
||||
|
||||
@Override
|
||||
public long beginZone(long srcLoc) {
|
||||
return JNI.invokePJ(srcLoc, 1, sym.zoneBegin);
|
||||
final SlotArena arena = slots.get();
|
||||
final long slot = arena.top();
|
||||
if (slot == NULL) return 0L;
|
||||
JNI.invokePPV(srcLoc, 1, slot, sym.zoneBegin);
|
||||
if (memGetInt(slot + ACTIVE_OFFSET) == 0) return 0L;
|
||||
arena.depth++;
|
||||
return slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endZone(long ctx) {
|
||||
JNI.invokeJV(ctx, sym.zoneEnd);
|
||||
if (ctx == 0L) return;
|
||||
slots.get().unwindTo(ctx);
|
||||
JNI.invokePV(ctx, sym.zoneEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoneText(long ctx, String text) {
|
||||
if (ctx == 0L) return;
|
||||
try (MemoryStack stack = stackPush()) {
|
||||
final ByteBuffer utf8 = stack.UTF8(truncate(text), false);
|
||||
JNI.invokeJPPV(ctx, memAddress(utf8), utf8.remaining(), sym.zoneText);
|
||||
JNI.invokePPPV(ctx, memAddress(utf8), utf8.remaining(), sym.zoneText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoneValue(long ctx, long value) {
|
||||
if (ctx == 0L) return;
|
||||
JNI.invokePJV(ctx, value, sym.zoneValue);
|
||||
}
|
||||
|
||||
@@ -153,19 +193,33 @@ public final class TracyClientBackend implements TracyBackend {
|
||||
|
||||
@Override
|
||||
public void plot(long namePtr, double value) {
|
||||
JNI.invokePJV(namePtr, Double.doubleToRawLongBits(value), sym.plot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(String text, int severity) {
|
||||
try (MemoryStack stack = stackPush()) {
|
||||
final LongBuffer arg0 = stack.longs(namePtr);
|
||||
final DoubleBuffer arg1 = stack.doubles(value);
|
||||
final PointerBuffer args = stack.pointers(memAddress(arg0), memAddress(arg1));
|
||||
LibFFI.ffi_call(plotCif, sym.plot, null, args);
|
||||
final ByteBuffer utf8 = stack.UTF8(truncate(text), false);
|
||||
JNI.invokePPV(severity, 0, 0, (long) utf8.remaining(), memAddress(utf8), sym.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(String text) {
|
||||
public long sectionEnter(int category, String text) {
|
||||
try (MemoryStack stack = stackPush()) {
|
||||
final ByteBuffer utf8 = stack.UTF8(truncate(text), false);
|
||||
JNI.invokePPV(memAddress(utf8), (long) utf8.remaining(), 0, sym.message);
|
||||
return Integer.toUnsignedLong(JNI.invokePI(category, memAddress(stack.UTF8(truncate(text), true)), sym.sectionEnter));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sectionLeave(long id) {
|
||||
JNI.invokeV((int) id, sym.sectionLeave);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sectionSetup(int category, String name) {
|
||||
try (MemoryStack stack = stackPush()) {
|
||||
JNI.invokePV(category, memAddress(stack.UTF8(truncate(name), true)), sym.sectionSetup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,15 +245,15 @@ public final class TracyClientBackend implements TracyBackend {
|
||||
@Override
|
||||
public void shutdown() {
|
||||
JNI.invokeV(sym.shutdownProfiler);
|
||||
for (SlotArena arena = ARENAS.poll(); arena != null; arena = ARENAS.poll()) {
|
||||
MemoryUtil.nmemFree(arena.base);
|
||||
}
|
||||
}
|
||||
|
||||
private static String truncate(String text) {
|
||||
return text.length() > MAX_TEXT ? text.substring(0, MAX_TEXT) : text;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPU zones: port of TracyOpenGL.hpp GpuCtx (v0.13.1).
|
||||
*/
|
||||
private static final int GPU_QUERY_COUNT = 16 * 1024;
|
||||
private static final byte GPU_CONTEXT_ID = 0;
|
||||
private static final byte GPU_CONTEXT_TYPE_OPENGL = 1;
|
||||
|
||||
@@ -11,6 +11,7 @@ import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
final class TracyLibrary {
|
||||
private static final Logger LOGGER = LogManager.getLogger("Tracy");
|
||||
|
||||
final long zoneCtxSize;
|
||||
final long startupProfiler;
|
||||
final long shutdownProfiler;
|
||||
final long profilerStarted;
|
||||
@@ -26,6 +27,9 @@ final class TracyLibrary {
|
||||
final long message;
|
||||
final long messageAppinfo;
|
||||
final long setThreadName;
|
||||
final long sectionEnter;
|
||||
final long sectionLeave;
|
||||
final long sectionSetup;
|
||||
final long gpuZoneBegin;
|
||||
final long gpuZoneEnd;
|
||||
final long gpuTime;
|
||||
@@ -43,21 +47,25 @@ final class TracyLibrary {
|
||||
}
|
||||
|
||||
private TracyLibrary(SharedLibrary lib) {
|
||||
zoneCtxSize = req(lib, "ang_zone_ctx_size");
|
||||
startupProfiler = req(lib, "___tracy_startup_profiler");
|
||||
shutdownProfiler = req(lib, "___tracy_shutdown_profiler");
|
||||
profilerStarted = req(lib, "___tracy_profiler_started");
|
||||
connected = req(lib, "___tracy_connected");
|
||||
zoneBegin = req(lib, "___tracy_emit_zone_begin");
|
||||
zoneEnd = req(lib, "___tracy_emit_zone_end");
|
||||
zoneText = req(lib, "___tracy_emit_zone_text");
|
||||
zoneValue = req(lib, "___tracy_emit_zone_value");
|
||||
zoneBegin = req(lib, "ang_zone_begin");
|
||||
zoneEnd = req(lib, "ang_zone_end");
|
||||
zoneText = req(lib, "ang_zone_text");
|
||||
zoneValue = req(lib, "ang_zone_value");
|
||||
frameMark = req(lib, "___tracy_emit_frame_mark");
|
||||
plot = req(lib, "___tracy_emit_plot");
|
||||
plot = req(lib, "ang_plot");
|
||||
plotInt = req(lib, "___tracy_emit_plot_int");
|
||||
plotConfig = req(lib, "___tracy_emit_plot_config");
|
||||
message = req(lib, "___tracy_emit_message");
|
||||
message = req(lib, "___tracy_emit_logString");
|
||||
messageAppinfo = req(lib, "___tracy_emit_message_appinfo");
|
||||
setThreadName = req(lib, "___tracy_set_thread_name");
|
||||
sectionEnter = req(lib, "ang_section_enter");
|
||||
sectionLeave = req(lib, "ang_section_leave");
|
||||
sectionSetup = req(lib, "ang_section_setup");
|
||||
gpuZoneBegin = req(lib, "___tracy_emit_gpu_zone_begin");
|
||||
gpuZoneEnd = req(lib, "___tracy_emit_gpu_zone_end");
|
||||
gpuTime = req(lib, "___tracy_emit_gpu_time");
|
||||
|
||||
@@ -47,7 +47,7 @@ final class TracyNativeLoader {
|
||||
case MACOS -> "libTracyClient.dylib";
|
||||
case LINUX -> "libTracyClient.so";
|
||||
};
|
||||
final String resource = "/natives/tracy/" + platform + "/" + libName;
|
||||
final String resource = "/natives/tracy/" + TRACY_VERSION + "/" + platform + "/" + libName;
|
||||
|
||||
final byte[] lib;
|
||||
try (InputStream in = TracyNativeLoader.class.getResourceAsStream(resource)) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(angelica-tracy-native CXX)
|
||||
|
||||
if(NOT DEFINED TRACY_SRC_DIR)
|
||||
message(FATAL_ERROR "TRACY_SRC_DIR must be set to a Tracy source checkout")
|
||||
endif()
|
||||
|
||||
add_subdirectory("${TRACY_SRC_DIR}" tracy)
|
||||
|
||||
target_sources(TracyClient PRIVATE "${CMAKE_CURRENT_LIST_DIR}/angelica_tracy_shim.cpp")
|
||||
target_include_directories(TracyClient PRIVATE "${TRACY_SRC_DIR}/public")
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "tracy/TracyC.h"
|
||||
#include "client/TracyProfiler.hpp"
|
||||
#include "common/TracyApi.h"
|
||||
|
||||
|
||||
static_assert(offsetof(TracyCZoneCtx, active) == 4, "TracyClientBackend.ACTIVE_OFFSET reads the active flag at a fixed offset of 4");
|
||||
|
||||
// Shim to cover things not reachable, or not efficiently usable, from Java; including header-inlined functions.
|
||||
extern "C" {
|
||||
|
||||
TRACY_API uint64_t ang_zone_ctx_size(void) {
|
||||
return (uint64_t)sizeof(TracyCZoneCtx);
|
||||
}
|
||||
|
||||
TRACY_API void ang_zone_begin(const struct ___tracy_source_location_data* srcloc, int32_t active, void* out) {
|
||||
*(TracyCZoneCtx*)out = ___tracy_emit_zone_begin(srcloc, active);
|
||||
}
|
||||
|
||||
TRACY_API void ang_zone_end(const void* ctx) {
|
||||
___tracy_emit_zone_end(*(const TracyCZoneCtx*)ctx);
|
||||
}
|
||||
|
||||
TRACY_API void ang_zone_text(const void* ctx, const char* txt, uint64_t size) {
|
||||
___tracy_emit_zone_text(*(const TracyCZoneCtx*)ctx, txt, (size_t)size);
|
||||
}
|
||||
|
||||
TRACY_API void ang_zone_value(const void* ctx, uint64_t value) {
|
||||
___tracy_emit_zone_value(*(const TracyCZoneCtx*)ctx, value);
|
||||
}
|
||||
|
||||
TRACY_API void ang_plot(const char* name, int64_t valueBits) {
|
||||
double value;
|
||||
memcpy(&value, &valueBits, sizeof(value));
|
||||
___tracy_emit_plot(name, value);
|
||||
}
|
||||
|
||||
TRACY_API uint32_t ang_section_enter(uint32_t category, const char* txt) {
|
||||
return tracy::Profiler::SectionEnter((uint16_t)category, "%s", txt);
|
||||
}
|
||||
|
||||
TRACY_API void ang_section_leave(uint32_t id) {
|
||||
tracy::Profiler::SectionLeave(id);
|
||||
}
|
||||
|
||||
TRACY_API void ang_section_setup(uint32_t category, const char* txt) {
|
||||
tracy::Profiler::SectionSetup((uint16_t)category, "%s", txt);
|
||||
}
|
||||
|
||||
}
|
||||
+24
-6
@@ -34,7 +34,7 @@ class TracyBindingSmokeTest {
|
||||
static boolean nativePresent() {
|
||||
for (String platform : new String[] {"windows-x64", "linux-x64", "macos-x64", "macos-arm64"}) {
|
||||
for (String lib : new String[] {"TracyClient.dll", "libTracyClient.so", "libTracyClient.dylib"}) {
|
||||
if (TracyBindingSmokeTest.class.getResource("/natives/tracy/" + platform + "/" + lib) != null) {
|
||||
if (TracyBindingSmokeTest.class.getResource("/natives/tracy/" + TracyTags.TRACY_VERSION + "/" + platform + "/" + lib) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,26 @@ class TracyBindingSmokeTest {
|
||||
return backend;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
void nativeIsBuiltWithOnDemand() throws Exception {
|
||||
assertEquals(16, backend().zoneCtxSize(), "ctx size is 16 only with TRACY_ON_DEMAND");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
void zeroHandlesAreInertWhileDisconnected() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
assertEquals(0L, b.beginZone(b.internSrcLoc("disconnected", 0)), "zone must be inactive with no profiler attached");
|
||||
b.endZone(0L);
|
||||
b.zoneText(0L, "text");
|
||||
b.zoneValue(0L, 1L);
|
||||
assertEquals(0L, b.sectionEnter(1, "disconnected section"));
|
||||
b.sectionLeave(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
void internAndSingleZone() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
final long srcLoc = b.internSrcLoc("smoke", 0);
|
||||
@@ -72,7 +90,7 @@ class TracyBindingSmokeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
@Order(3)
|
||||
void hammerZonesAcrossThreads() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
final int threads = 4;
|
||||
@@ -108,7 +126,7 @@ class TracyBindingSmokeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
@Order(4)
|
||||
void plotsMessagesAndFrameMarks() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
final long plotName = b.internPlotName("smokePlot", 0);
|
||||
@@ -126,7 +144,7 @@ class TracyBindingSmokeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
@Order(5)
|
||||
void dynamicSrcLocOverflowPath() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
final long dynamic = b.dynamicSrcLoc();
|
||||
@@ -137,7 +155,7 @@ class TracyBindingSmokeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
@Order(6)
|
||||
void gpuEmitStructMarshalling() throws Exception {
|
||||
final TracyClientBackend b = backend();
|
||||
final long srcLoc = b.internSrcLoc("gpu-smoke", 0);
|
||||
@@ -152,7 +170,7 @@ class TracyBindingSmokeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
@Order(7)
|
||||
void shutdownFlushes() throws Exception {
|
||||
backend().shutdown();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user