Skip to content

Commit eb9d8a1

Browse files
committed
Merge branch 'dev/kslawicki/volumetric_quality_presets_fix' into 'main'
REMIX-5532 Fixes inverted/stale behavior for the RTX Volumetric Settings quality preset. See merge request lightspeedrtx/dxvk-remix-nv!2192
2 parents 7f191f5 + 4b27ad7 commit eb9d8a1

3 files changed

Lines changed: 26 additions & 29 deletions

File tree

src/dxvk/imgui/dxvk_imgui_about.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (c) 2022-2026, NVIDIA CORPORATION. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -131,6 +131,7 @@ namespace dxvk {
131131
"Jerran Schmidt",
132132
"Sascha Sertel",
133133
"Jeremy Shopf",
134+
"Kamil Slawicki",
134135
"Nuno Subtil",
135136
"Ilya Terentiev",
136137
"Peter Thacker",

src/dxvk/rtx_render/rtx_global_volumetrics.cpp

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ namespace dxvk {
172172

173173
RtxGlobalVolumetrics::RtxGlobalVolumetrics(DxvkDevice* device) : CommonDeviceObject(device), RtxPass(device) {}
174174

175+
void RtxGlobalVolumetrics::onFroxelResourceOptionsChanged(DxvkDevice* device) {
176+
if (device == nullptr) {
177+
return;
178+
}
179+
180+
device->getCommon()->metaGlobalVolumetrics().m_rebuildFroxels = true;
181+
}
182+
175183
// Quality level presets, x component controls the froxelGridResolutionScale and the y component controls the froxelDepthSlices settings.
176184
static const int2 qualityModes[RtxGlobalVolumetrics::QualityLevel::QualityCount] = {
177185
int2(32, 48),
@@ -228,8 +236,8 @@ namespace dxvk {
228236
RemixGui::Checkbox("Show Advanced Options", &showAdvanced);
229237

230238
if (showAdvanced) {
231-
m_rebuildFroxels |= RemixGui::DragInt("Froxel Grid Resolution Scale", &froxelGridResolutionScaleObject(), 0.1f, 1);
232-
m_rebuildFroxels |= RemixGui::DragInt("Froxel Depth Slices", &froxelDepthSlicesObject(), 0.1f, 1, UINT16_MAX);
239+
RemixGui::DragInt("Froxel Grid Resolution Scale", &froxelGridResolutionScaleObject(), 0.1f, 1);
240+
RemixGui::DragInt("Froxel Depth Slices", &froxelDepthSlicesObject(), 0.1f, 1, UINT16_MAX);
233241
RemixGui::DragInt("Max Accumulation Frames", &maxAccumulationFramesObject(), 0.1f, 1, UINT8_MAX);
234242
RemixGui::DragFloat("Froxel Depth Slice Distribution Exponent", &froxelDepthSliceDistributionExponentObject(), 0.01f, 0.0f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
235243
RemixGui::DragFloat("Froxel Max Distance", &froxelMaxDistanceMetersObject(), 0.25f, 0.0f, FLT_MAX, "%.2f", ImGuiSliderFlags_AlwaysClamp);
@@ -242,8 +250,8 @@ namespace dxvk {
242250

243251
ImGui::BeginDisabled(enableReferenceMode());
244252

245-
m_rebuildFroxels |= RemixGui::DragInt("Restir Grid Downsample Factor", &restirGridScaleObject(), 0.1f, 1);
246-
m_rebuildFroxels |= RemixGui::DragInt("Restir Froxel Depth Slices", &restirFroxelDepthSlicesObject(), 0.1f, 1, UINT16_MAX);
253+
RemixGui::DragInt("Restir Grid Downsample Factor", &restirGridScaleObject(), 0.1f, 1);
254+
RemixGui::DragInt("Restir Froxel Depth Slices", &restirFroxelDepthSlicesObject(), 0.1f, 1, UINT16_MAX);
247255
RemixGui::DragFloat("Restir Guard Band Scale Factor", &restirGridGuardBandFactorObject(), 0.1f, 1.0f, FLT_MAX, "%.3f", ImGuiSliderFlags_AlwaysClamp);
248256

249257
RemixGui::DragInt("Initial RIS Sample Count", &initialRISSampleCountObject(), 0.05f, 1, UINT8_MAX);
@@ -404,24 +412,8 @@ namespace dxvk {
404412
qualityPreset = qualityModes[desiredQualityLevel];
405413
}
406414

407-
// Set new values based on preset values and cache old values
408-
409-
const auto newFroxelGridResolutionScale = qualityPreset.x;
410-
const auto newFroxelDepthSlices = qualityPreset.y;
411-
const auto oldFroxelGridResolutionScale = froxelGridResolutionScale();
412-
const auto oldFroxelDepthSlices = froxelDepthSlices();
413-
414-
froxelGridResolutionScale.setDeferred(newFroxelGridResolutionScale);
415-
froxelDepthSlices.setDeferred(newFroxelDepthSlices);
416-
417-
// Indicate that the froxel resources should be rebuilt if any relevant values changed
418-
419-
if (
420-
newFroxelGridResolutionScale != oldFroxelGridResolutionScale ||
421-
newFroxelDepthSlices != oldFroxelDepthSlices
422-
) {
423-
m_rebuildFroxels = true;
424-
}
415+
froxelGridResolutionScale.setDeferred(static_cast<uint32_t>(qualityPreset.x));
416+
froxelDepthSlices.setDeferred(static_cast<uint16_t>(qualityPreset.y));
425417
}
426418

427419
void RtxGlobalVolumetrics::setPreset(const PresetType presetType) {
@@ -798,7 +790,6 @@ namespace dxvk {
798790

799791
if (m_rebuildFroxels) {
800792
createDownscaledResource(ctx, frameBeginCtx.downscaledExtent);
801-
m_rebuildFroxels = false;
802793
}
803794
}
804795

@@ -832,6 +823,8 @@ namespace dxvk {
832823

833824
m_volumeReservoirs[0] = Resources::createImageResource(ctx, "volume reservoir 0", restirFroxelGridFullDimensions, VK_FORMAT_R32G32B32A32_UINT, 1, VK_IMAGE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D);
834825
m_volumeReservoirs[1] = Resources::createImageResource(ctx, "volume reservoir 1", restirFroxelGridFullDimensions, VK_FORMAT_R32G32B32A32_UINT, 1, VK_IMAGE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D);
826+
827+
m_rebuildFroxels = false;
835828
}
836829

837830
void RtxGlobalVolumetrics::releaseDownscaledResource() {

src/dxvk/rtx_render/rtx_global_volumetrics.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ namespace dxvk {
7575
anisotropy(aniso) { }
7676
};
7777

78+
static void onFroxelResourceOptionsChanged(DxvkDevice* device);
79+
7880
// Froxel Radiance Cache/Volumetric Lighting ptions
7981
// Note: The effective froxel grid resolution (based on the resolution scale) and froxelDepthSlices when multiplied together give the number of froxel cells, and this should be greater than the maximum number of
8082
// "concurrent" threads the GPU can execute at once to saturate execution and ensure maximal occupancy. This can be calculated by looking at how many warps per multiprocessor the GPU can have at once (This can
@@ -83,15 +85,16 @@ namespace dxvk {
8385
// Example for a RTX 3090: 82 SMs * 64 warps per SM * 32 threads per warp = 167,936 froxels to saturate the GPU. It is fine to be a bit below this though as most gpus will have fewer SMs than this, and higher resolutions
8486
// will also use more froxels due to how the grid is allocated with respect to the (downscaled when DLSS is in use) resolution, and we don't want the froxel passes to be too expensive (unless higher quality results are desired).
8587
RTX_OPTION("rtx.volumetrics", float, restirGridGuardBandFactor, 1.1f, "The scale factor for the restir grid guard band, which is an extended part of the viewing frustum for which we should calculate lighting information for, even though they are technically offscreen. This helps reduce noise in cases where the camera is moving around.");
86-
RTX_OPTION("rtx.volumetrics", uint32_t, restirGridScale, 4,
88+
RTX_OPTION_ARGS("rtx.volumetrics", uint32_t, restirGridScale, 4,
8789
"The scale factor to divide the x and y froxel grid resolution by to determine the x and y dimensions of the ReSTIR froxel grid.\n"
88-
"Note that unlike the rtx.volumetrics.froxelGridResolutionScale option this is not dividing the render resolution, but rather is a scalar on top of the resulting froxel grid resolution after it is divided by the resolution scale.");
90+
"Note that unlike the rtx.volumetrics.froxelGridResolutionScale option this is not dividing the render resolution, but rather is a scalar on top of the resulting froxel grid resolution after it is divided by the resolution scale.",
91+
args.onChangeCallback = &onFroxelResourceOptionsChanged);
8992
RTX_OPTION_ARGS("rtx.volumetrics", uint32_t, froxelGridResolutionScale, 8, "The scale factor to divide the x and y render resolution by to determine the x and y dimensions of the froxel grid.",
90-
args.minValue = static_cast<uint32_t>(1), args.flags = RtxOptionFlags::UserSetting);
93+
args.minValue = static_cast<uint32_t>(1), args.onChangeCallback = &onFroxelResourceOptionsChanged, args.flags = RtxOptionFlags::UserSetting);
9194
RTX_OPTION_ARGS("rtx.volumetrics", uint16_t, froxelDepthSlices, 64, "The z dimension of the froxel grid. Must be constant after initialization.",
92-
args.minValue = static_cast<uint16_t>(1), args.maxValue = std::numeric_limits<uint16_t>::max(), args.flags = RtxOptionFlags::UserSetting);
95+
args.minValue = static_cast<uint16_t>(1), args.maxValue = std::numeric_limits<uint16_t>::max(), args.onChangeCallback = &onFroxelResourceOptionsChanged, args.flags = RtxOptionFlags::UserSetting);
9396
RTX_OPTION_ARGS("rtx.volumetrics", uint16_t, restirFroxelDepthSlices, 128, "The z dimension of the ReSTIR froxel grid. Must be constant after initialization.",
94-
args.minValue = static_cast<uint16_t>(1), args.maxValue = std::numeric_limits<uint16_t>::max());
97+
args.minValue = static_cast<uint16_t>(1), args.maxValue = std::numeric_limits<uint16_t>::max(), args.onChangeCallback = &onFroxelResourceOptionsChanged);
9598
RTX_OPTION_ARGS("rtx.volumetrics", uint8_t, maxAccumulationFrames, 128,
9699
"The number of frames to accumulate volume lighting samples over, maximum of 254.\n"
97100
"Large values result in greater image stability at the cost of potentially more temporal lag."

0 commit comments

Comments
 (0)