Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 83 additions & 0 deletions docs/rtx30-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# RTX 30 compatibility

Caustica automatically selects a portable Vulkan ray-tracing path when
shader execution reordering is unavailable.

## Default policy

```toml
[compatibility]
as-lane-mode = "auto"
omm-mode = "auto"
```

Both settings are selected during Vulkan device and executor creation.
Changing either setting requires a complete game restart.

## Expected RTX 30 behavior

The default RTX 30 path should report:

* Hardware profile: `nvidia-portable-rt`
* Trace backend: `portable-TraceRay`
* SER backend: `none`
* AS lane mode: `serialized`
* OMM policy: `auto`
* OMM effective state: disabled
* OMM reason: `disabled-on-nvidia-portable-profile`

The renderer must use the packaged `_base` ray-generation shaders.

## AS lane modes

### `auto`

Resolves to `serialized`. This is the supported default.

### `serialized`

Orders compute-side acceleration-structure work against graphics-side
terrain/TLAS use with timeline-semaphore waits.

### `overlap`

Experimental. Omits the cross-lane serialization wait. Do not use this
mode for release qualification.

## OMM modes

### `auto`

Uses capability-driven policy. OMM is suppressed on the NVIDIA portable
profile where SER is unavailable.

### `off`

Always disables OMM.

### `on`

Requests OMM when the physical device reports support. This is an
experimental override and is not part of RTX 30 release qualification.

## Failure behavior

If OMM was requested but its Vulkan entry points are unavailable,
Caustica disables OMM and continues without it.

Missing mandatory ray-tracing pipeline, acceleration-structure, or
TraceRays entry points remain a bring-up failure.

## Reporting a compatibility result

Include:

* Caustica commit SHA
* Production artifact SHA-256
* GPU model
* Operating system
* NVIDIA driver version
* Full `RT compatibility:` log line
* Full `RT bring-up OK` line
* Vulkan validation messages
* Test scenarios completed
Empty file modified gradlew
100644 → 100755
Empty file.
47 changes: 45 additions & 2 deletions src/main/java/dev/comfyfluffy/caustica/CausticaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
public final class CausticaConfig {
private static final Logger LOGGER = LoggerFactory.getLogger("Caustica");
private static final List<RuntimeSetting<?>> SETTINGS = new CopyOnWriteArrayList<>();
static final int CONFIG_SCHEMA_VERSION = 14;
static final int CONFIG_SCHEMA_VERSION = 15;

private static final Path CONFIG_PATH = resolveConfigPath();
private static final CommentedFileConfig FILE = loadAndMigrateFile(CONFIG_PATH);
Expand Down Expand Up @@ -83,6 +83,7 @@ public static void ensureRegistered() {
Rt.Terrain.ASYNC_DISPATCH_PER_PASS, Rt.Terrain.COMPLETION_RESULTS_PER_PASS,
Rt.Terrain.MAX_INFLIGHT_SECTIONS, Rt.Terrain.STREAM_BUDGET_MS,
Rt.Terrain.STREAM_BUDGET_MAX_MS, Rt.Terrain.STREAM_FALLBACK_BUDGET_MS, Rt.Omm.ENABLED,
Rt.Compatibility.AS_LANE_MODE, Rt.Compatibility.OMM_MODE,
Rt.Entities.ENABLED, Rt.Entities.GLOW_ENABLED, Rt.FirstPerson.ENABLED,
Rt.FirstPerson.DISABLE_VANILLA_MODEL, Rt.EntityTextures.MAX_TEXTURES,
Rt.Reconstruction.BACKEND, Rt.DlssRr.ENABLED, Rt.DlssRr.DIFFUSE_PATH_GUIDE,
Expand Down Expand Up @@ -187,6 +188,12 @@ private static void writeComments() {
+ " grid are always active whenever RIS is on. min-fill-ratio drops emissive footprints\n"
+ " below that fraction of their bounding rectangle (speckle/sparse crossed planes), so\n"
+ " only reasonably compact glows become lights. stats/dump/dump-radius are debug logging.");
FILE.setComment("compatibility",
" Driver and hardware compatibility policy. These settings are selected during Vulkan\n"
+ " device/executor creation and require a restart.\n"
+ " as-lane-mode: auto, serialized, or overlap.\n"
+ " omm-mode: auto, on, or off. Auto suppresses OMM on NVIDIA portable-RT\n"
+ " hardware where SER is unavailable; on explicitly requests OMM when supported.");
FILE.setComment("offline-renderer",
" Uncapped progressive native-resolution rendering started with F7.\n"
+ " The scene, camera, water time, and exposure are frozen for the session.\n"
Expand Down Expand Up @@ -373,15 +380,23 @@ static boolean migrateLegacySceneConfig(CommentedConfig config) {
if (version < 14) {
applySchema14Defaults(config);
}
if (version == 14) {
applySchema15CompatibilityDefaults(config);
}
config.set("config-version", CONFIG_SCHEMA_VERSION);
return true;
}

private static void applySchema14Defaults(CommentedConfig config) {
migrateExactNumber(config, "composite.max-bounces", 8.0, 64.0);
config.remove("composite.celestial-light-bounces");
}

private static void applySchema15CompatibilityDefaults(CommentedConfig config) {
// Only schema-14 files could have received the faulty generated defaults in the prior release.
migrateExactNumber(config, "composite.max-bounces", 64.0, 8.0);
migrateExactNumber(config, "lights.ris-candidates", 8.0, 0.0);
}

private static boolean isNrdBackend(CommentedConfig config) {
Object rawBackend = config.get("reconstruction.backend");
return rawBackend instanceof String value && "nrd".equalsIgnoreCase(value.trim());
Expand Down Expand Up @@ -1041,6 +1056,34 @@ private Omm() {
}
}

public static final class Compatibility {
public static final StringSetting AS_LANE_MODE = string(
"caustica.rt.asLaneMode", "compatibility.as-lane-mode", "auto",
Compatibility::sanitizeAsLaneMode);
public static final StringSetting OMM_MODE = string(
"caustica.rt.ommMode", "compatibility.omm-mode", "auto",
Compatibility::sanitizeOmmMode);

private Compatibility() {
}

private static String sanitizeAsLaneMode(String value) {
String normalized = value == null ? "" : value.trim().toLowerCase(Locale.ROOT);
return switch (normalized) {
case "serialized", "overlap" -> normalized;
default -> "auto";
};
}

private static String sanitizeOmmMode(String value) {
String normalized = value == null ? "" : value.trim().toLowerCase(Locale.ROOT);
return switch (normalized) {
case "on", "off" -> normalized;
default -> "auto";
};
}
}

public static final class Sharc {
public static final BooleanSetting ENABLED = bool("caustica.rt.sharc", "sharc.enabled", true);
public static final IntSetting CACHE_EXPONENT =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,12 @@ private static void applyCommand(Minecraft client) {
setBoolean(command, "frameStats", CausticaConfig.Rt.FrameStats.ENABLED);
boolean terrainSettingsChanged = command.containsKey("terrainDispatch")
|| command.containsKey("terrainResults") || command.containsKey("terrainInflight")
|| command.containsKey("terrainBuildBatch") || command.containsKey("omm")
|| command.containsKey("terrainBuildBatch")
|| command.containsKey("ommSubdivision");
setInt(command, "terrainDispatch", CausticaConfig.Rt.Terrain.ASYNC_DISPATCH_PER_PASS);
setInt(command, "terrainResults", CausticaConfig.Rt.Terrain.COMPLETION_RESULTS_PER_PASS);
setInt(command, "terrainInflight", CausticaConfig.Rt.Terrain.MAX_INFLIGHT_SECTIONS);
setInt(command, "terrainBuildBatch", CausticaConfig.Rt.Terrain.GPU_BUILD_BATCH_SIZE);
setBoolean(command, "omm", CausticaConfig.Rt.Omm.ENABLED);
setInt(command, "ommSubdivision", CausticaConfig.Rt.Omm.SUBDIVISION);
if (terrainSettingsChanged) RtTerrain.requestFullClear();
String terrainBenchmark = command.getProperty("terrainBenchmark");
Expand Down Expand Up @@ -269,6 +268,16 @@ private static void publishState(Minecraft client) {
state.setProperty("outputScaleFailure", RtComposite.INSTANCE.outputScaleFailure());
state.setProperty("backend", RtRuntimeStatus.backend());
state.setProperty("rtRequested", Boolean.toString(RtDeviceBringup.rtRequested()));
state.setProperty("hardwareProfile", RtDeviceBringup.hardwareProfile());
state.setProperty("portableTraceBackend", Boolean.toString(RtDeviceBringup.portableTraceBackend()));
state.setProperty("serBackend", RtDeviceBringup.serBackendLabel());
state.setProperty("ommSupported", Boolean.toString(RtDeviceBringup.opacityMicromapSupported()));
state.setProperty("ommPolicy", RtDeviceBringup.ommPolicy());
state.setProperty("ommEffective", Boolean.toString(RtDeviceBringup.ommEnabled()));
state.setProperty("ommReason", RtDeviceBringup.ommEffectiveReason());
state.setProperty("driverRaw", Integer.toHexString(RtDeviceBringup.rawDriverVersion()));
state.setProperty("asLaneMode", RtRuntimeStatus.actualAsLaneMode());
state.setProperty("asLaneModeConfigured", CausticaConfig.Rt.Compatibility.AS_LANE_MODE.get());
state.setProperty("rtContextReady", Boolean.toString(RtRuntimeStatus.rtContextReady()));
state.setProperty("rtFailureLatched", Boolean.toString(RtComposite.INSTANCE.hasFailed()));
state.setProperty("rtStatus", RtRuntimeStatus.unavailableReason());
Expand All @@ -284,6 +293,9 @@ private static void publishState(Minecraft client) {
state.setProperty("terrainGpuQueueDepth", Integer.toString(terrain.gpuQueueDepth()));
state.setProperty("terrainBuildsSubmitted", Long.toString(terrain.buildsSubmitted()));
state.setProperty("terrainBuildsPublished", Long.toString(terrain.buildsPublished()));
state.setProperty("terrainInteractiveOutstanding", Long.toString(RtTerrain.interactiveOutstanding()));
state.setProperty("terrainInteractiveSubmitted", Long.toString(RtTerrain.interactiveSubmittedTotal()));
state.setProperty("terrainInteractivePublished", Long.toString(RtTerrain.interactivePublishedTotal()));
state.setProperty("terrainBuildLatencyNanos", Long.toString(terrain.lastBuildLatencyNanos()));
state.setProperty("terrainBuildLatencyKind", "host-submit-to-timeline-completion");
state.setProperty("terrainActiveCompactionQueries", Integer.toString(terrain.activeCompactionQueries()));
Expand All @@ -294,7 +306,8 @@ private static void publishState(Minecraft client) {
state.setProperty("terrainResults", Integer.toString(CausticaConfig.Rt.Terrain.COMPLETION_RESULTS_PER_PASS.value()));
state.setProperty("terrainInflight", Integer.toString(CausticaConfig.Rt.Terrain.MAX_INFLIGHT_SECTIONS.value()));
state.setProperty("terrainBuildBatch", Integer.toString(CausticaConfig.Rt.Terrain.GPU_BUILD_BATCH_SIZE.value()));
state.setProperty("terrainOmm", Boolean.toString(CausticaConfig.Rt.Omm.ENABLED.value()));
state.setProperty("terrainOmm", Boolean.toString(RtDeviceBringup.ommEnabled()));
state.setProperty("terrainOmmConfigured", Boolean.toString(CausticaConfig.Rt.Omm.ENABLED.value()));
state.setProperty("terrainOmmSubdivision", Integer.toString(CausticaConfig.Rt.Omm.SUBDIVISION.value()));
state.setProperty("terrainBenchmarkStartedNanos", Long.toString(streaming.startedNanos()));
state.setProperty("terrainDesired", Integer.toString(streaming.desired()));
Expand Down
Loading
Loading