Skip to content

Commit

Permalink
Merge branch 'dev/adunn/unordered_resolve_stochastic' into 'main'
Browse files Browse the repository at this point in the history
GPU Perf: Probabilistic Indirect Unordered Resolve

See merge request lightspeedrtx/dxvk-remix-nv!957
  • Loading branch information
AlexDunn committed Aug 19, 2024
2 parents 7a7db19 + 7da3583 commit b698be7
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 21 deletions.
1 change: 1 addition & 0 deletions RtxOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
|rtx.enablePortalFadeInEffect|bool|False||
|rtx.enablePresentThrottle|bool|False|A flag to enable or disable present throttling, when set to true a sleep for a time specified by the throttle delay will be inserted into the DXVK presentation thread\.<br>Useful to manually reduce the framerate if the application is running too fast or to reduce GPU power usage during development to keep temperatures down\.<br>Should not be enabled in anything other than development situations\.|
|rtx.enablePreviousTLAS|bool|True||
|rtx.enableProbabilisticUnorderedResolveInIndirectRays|bool|True|A flag to enable or disable probabilistic unordered resolve approximations in indirect rays\.<br>This flag speeds up the unordered resolve for indirect rays by probabilistically deciding when to perform unordered resolve or not\. Must have both unordered resolve and unordered resolve in indirect rays enabled for this to take effect\.<br>This option should be enabled by default as it can significantly improve performance on some hardware\. In rare cases it may come at the cost of some quality for particles and decals in reflections\.<br>Note that even with this option enabled, unordered resolve approximations are only done on the first indirect bounce for the sake of performance overall\.|
|rtx.enableRayReconstruction|bool|True|Enable ray reconstruction\.|
|rtx.enableRaytracing|bool|True|Globally enables or disables ray tracing\. When set to false the original game should render mostly as it would in DXVK typically\.<br>Some artifacts may still appear however compared to the original game either due to issues with the underlying DXVK translation or issues in Remix itself\.|
|rtx.enableReplacementAssets|bool|True|Globally enables or disables all enhanced asset replacement \(materials, meshes, lights\) functionality\.|
Expand Down
5 changes: 4 additions & 1 deletion src/dxvk/imgui/dxvk_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2605,7 +2605,10 @@ namespace dxvk {
ImGui::Checkbox("Enable Secondary Bounces", &RtxOptions::Get()->enableSecondaryBouncesObject());
ImGui::Checkbox("Enable Russian Roulette", &RtxOptions::Get()->enableRussianRouletteObject());
ImGui::Checkbox("Enable Probability Dithering Filtering for Primary Bounce", &RtxOptions::Get()->enableFirstBounceLobeProbabilityDitheringObject());
ImGui::Checkbox("Unordered Resolve in Indirect Rays", &RtxOptions::Get()->enableUnorderedResolveInIndirectRaysObject());
ImGui::Checkbox("Unordered Resolve in Indirect Rays", &RtxOptions::enableUnorderedResolveInIndirectRaysObject());
ImGui::BeginDisabled(!RtxOptions::enableUnorderedResolveInIndirectRays());
ImGui::Checkbox("Probabilistic Unordered Resolve in Indirect Rays", &RtxOptions::enableProbabilisticUnorderedResolveInIndirectRaysObject());
ImGui::EndDisabled();
ImGui::Checkbox("Unordered Emissive Particles in Indirect Rays", &RtxOptions::Get()->enableUnorderedEmissiveParticlesInIndirectRaysObject());
ImGui::Checkbox("Transmission Approximation in Indirect Rays", &RtxOptions::Get()->enableTransmissionApproximationInIndirectRaysObject());
// # bounces limitted by 4b allocation in payload
Expand Down
1 change: 1 addition & 0 deletions src/dxvk/rtx_render/rtx_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ namespace dxvk {
constants.enhanceBSDFIndirectLightMinRoughness = m_common->metaComposite().dlssEnhancementIndirectLightMinRoughness();
constants.enableFirstBounceLobeProbabilityDithering = RtxOptions::Get()->isFirstBounceLobeProbabilityDitheringEnabled();
constants.enableUnorderedResolveInIndirectRays = RtxOptions::Get()->isUnorderedResolveInIndirectRaysEnabled();
constants.enableProbabilisticUnorderedResolveInIndirectRays = RtxOptions::enableProbabilisticUnorderedResolveInIndirectRays();
constants.enableTransmissionApproximationInIndirectRays = RtxOptions::Get()->enableTransmissionApproximationInIndirectRays();
constants.enableUnorderedEmissiveParticlesInIndirectRays = RtxOptions::Get()->enableUnorderedEmissiveParticlesInIndirectRays();
constants.enableDecalMaterialBlending = RtxOptions::Get()->isDecalMaterialBlendingEnabled();
Expand Down
5 changes: 5 additions & 0 deletions src/dxvk/rtx_render/rtx_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@ namespace dxvk {
"This allows for the presence of unordered approximations in resolving to be overridden in indirect rays and as such requires separate unordered approximations to be enabled to have any effect.\n"
"This option should be enabled if objects which can be resolvered in an unordered way in indirect rays are expected for higher quality in reflections, but may come at a performance cost.\n"
"Note that even with this option enabled, unordered resolve approximations are only done on the first indirect bounce for the sake of performance overall.");
RTX_OPTION("rtx", bool, enableProbabilisticUnorderedResolveInIndirectRays, true,
"A flag to enable or disable probabilistic unordered resolve approximations in indirect rays.\n"
"This flag speeds up the unordered resolve for indirect rays by probabilistically deciding when to perform unordered resolve or not. Must have both unordered resolve and unordered resolve in indirect rays enabled for this to take effect.\n"
"This option should be enabled by default as it can significantly improve performance on some hardware. In rare cases it may come at the cost of some quality for particles and decals in reflections.\n"
"Note that even with this option enabled, unordered resolve approximations are only done on the first indirect bounce for the sake of performance overall.");
RTX_OPTION_ENV("rtx", bool, enableUnorderedEmissiveParticlesInIndirectRays, false, "DXVK_EMISSIVE_INDIRECT_PARTICLES",
"A flag to enable or disable unordered resolve emissive particles specifically in indirect rays.\n"
"Should be enabled in higher quality rendering modes as emissive particles are fairly important in reflections, but may be disabled to skip such interactions which can improve performance on lower end hardware.\n"
Expand Down
4 changes: 2 additions & 2 deletions src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ void geometryResolverVertex(
unorderedRayMask, geometryResolverState.portalSpace,
useIntersectionBillboards,
geometryResolverState.pixelCoordinate,
geometryResolverState.accumulatedRotation, geometryResolverState.accumulatedHitDistance,
geometryResolverState.accumulatedRotation, geometryResolverState.accumulatedHitDistance, 1.h,
radianceAttenuation, emissiveRadiance,
numUnorderedInteractions,
geometryResolverState.decalEncountered, decalMemory, decalEmissiveRadiance, surfaceIndex);
Expand Down Expand Up @@ -1641,7 +1641,7 @@ void geometryPSRResolverVertex(
unorderedRayMask, geometryPSRResolverState.portalSpace,
/* useIntersectionBillboards = */ cb.enableBillboardOrientationCorrection,
u16vec2(65535, 65535),
geometryPSRResolverState.accumulatedRotation, geometryPSRResolverState.accumulatedHitDistance,
geometryPSRResolverState.accumulatedRotation, geometryPSRResolverState.accumulatedHitDistance, 1.h,
radianceAttenuation, emissiveRadiance,
numUnorderedInteractions,
geometryPSRResolverState.decalEncountered, decalMemory, decalEmissiveRadiance, surfaceIndex);
Expand Down
18 changes: 4 additions & 14 deletions src/dxvk/shaders/rtx/algorithm/integrator_indirect.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,6 @@ void evalEmission(
}


// Note: Using separate accumulation for particles and whatever else as while they should be visible in reflections
// through indirect paths, they do not need to be evaluated with particularly high quality. This is only done for the
// first bounce as past that all particles and similar things will be skipped anyways.
bool getSeparateUnorderedApproximationsActive(PathState pathState)
{
return
cb.enableSeparateUnorderedApproximations &&
cb.enableUnorderedResolveInIndirectRays &&
pathState.bounceIteration <= 1;
}

// Calculate a point's screen space position, if it's outside the screen, move it to screen boundary.
// Return if the point is inside the screen.
bool calculateScreenBoundedPixelCoordinate(mat4 transformMatrix, vec3 position, inout ivec2 pixelCoordinate)
Expand Down Expand Up @@ -194,7 +183,7 @@ void integratePathVertex(
IndirectPathTextures indirectPathTextures, RayHitInfo rayHitInfo,
inout PathState pathState)
{
const bool separateUnorderedApproximations = getSeparateUnorderedApproximationsActive(pathState);
const bool separateUnorderedApproximations = pathState.getSeparateUnorderedApproximationsActive();

// Setup resolve state

Expand Down Expand Up @@ -239,7 +228,7 @@ void integratePathVertex(
resolveMode, unorderedResolveRay,
unorderedRayMask, pathState.portalSpace,
/* useIntersectionBillboards = */ cb.enableBillboardOrientationCorrection,
pathState.accumulatedHitDistance,
pathState.accumulatedHitDistance, pathState.getUnorderedApproximationSelectionProbability(),
radianceAttenuation, emissiveRadiance,
numUnorderedInteractions,
pathState.decalEncountered, decalMemory, decalEmissiveRadiance, unorderedSurfaceIndex);
Expand Down Expand Up @@ -933,7 +922,8 @@ void integrateIndirectPath(
// Enable nee cache for PSR reflection, which cannot be handled by ReSTIR GI.
pathState.enableNeeCacheAfterFirstBounce =
(geometryFlags.performPSRR || NEECache.shouldUseHigherBounceNeeCache(geometryFlags.firstSampledLobeIsSpecular, calcRoughness(firstHitPerceptualRoughness)));

pathState.gbufferPerceptualRoughness = firstHitPerceptualRoughness;

if (NEE_CACHE_ENABLE && cb.neeCacheArgs.enable)
{
RAB_RandomSamplerState rtxdiRNG = RAB_InitRandomSampler(pathState.pixelCoordinate, cb.frameIdx, pathState.bounceIteration);
Expand Down
38 changes: 34 additions & 4 deletions src/dxvk/shaders/rtx/algorithm/path_state.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct PathState : IBasePayloadState
uint8_t _data; // PortalSpace(uint:2b),
// indirectLightPortalID(uint:2b),
// bounceIteration(uint:4b)

uint8_t _roughness;

// Property to get and set pixel coordinate
property u16vec2 pixelCoordinate
Expand Down Expand Up @@ -213,6 +213,12 @@ struct PathState : IBasePayloadState
set { }
}

property float16_t gbufferPerceptualRoughness
{
get { return unorm8ToF16(_roughness); }
set { _roughness = f16ToUnorm8(newValue); }
}

// Calculates an RNG offset at a start of a bounce set in the path state
uint calculateRNGOffset(uint sampleOffset)
{
Expand All @@ -224,19 +230,43 @@ struct PathState : IBasePayloadState
return sampleOffset;
}

// Note: Using separate accumulation for particles and whatever else as while they should be visible in reflections
// through indirect paths, they do not need to be evaluated with particularly high quality. This is only done for the
// first bounce as past that all particles and similar things will be skipped anyways.
bool getSeparateUnorderedApproximationsActive()
{
RNG rng = createRNG(pixelCoordinate, cb.frameIdx, 101);
return cb.enableSeparateUnorderedApproximations &&
cb.enableUnorderedResolveInIndirectRays &&
bounceIteration <= 1 &&
(!cb.enableProbabilisticUnorderedResolveInIndirectRays || getNextSampleBlueNoise(rng) <= getUnorderedApproximationSelectionProbability());
}

// Describe the rate at which we should perform unordered resolve for indirect rays.
static const float16_t kUnorderedResolveSelectionProbabilityMin = 1.h/16.h;
static const float16_t kUnorderedResolveSelectionProbabilityMax = 1.h/2.h;

float16_t getUnorderedApproximationSelectionProbability()
{
return cb.enableProbabilisticUnorderedResolveInIndirectRays
// Note: The use of gbuffer roughness here is just a rough estimator for how important a ray is to the overall path contribution.
// There are better estimators, however this one is basically free, and provides good quality. Ideally we want high probability
// when the ray is from a smooth material, and low probability when it is very rough.
? lerp(kUnorderedResolveSelectionProbabilityMax, kUnorderedResolveSelectionProbabilityMin, gbufferPerceptualRoughness)
: 1.h;
}

#if defined(RAY_PIPELINE) && defined(RT_SHADER_EXECUTION_REORDERING)
bool shouldReorder(out uint coherenceHints, out uint numCoherenceHints)
{
coherenceHints = 0;
numCoherenceHints = 0;

// getSeparateUnorderedApproximationsActive(...)
if (cb.enableSeparateUnorderedApproximations &&
cb.enableUnorderedResolveInIndirectRays)
{
addCoherenceHintAsLeastImportant1Bit(bounceIteration <= 1, coherenceHints, numCoherenceHints);
addCoherenceHintAsLeastImportant1Bit(getSeparateUnorderedApproximationsActive(), coherenceHints, numCoherenceHints);
}

return true;
}

Expand Down
4 changes: 4 additions & 0 deletions src/dxvk/shaders/rtx/algorithm/resolve.slangh
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,7 @@ void resolveVertexUnordered<let RAY_FLAGS : uint8_t>(
f16vec4 accumulatedRotation,
#endif
float accumulatedHitDistance,
float16_t pathSelectionProbability,
inout f16vec3 radianceAttenuation, inout vec3 emissiveRadiance,
out uint numInteractions,
inout bool decalEncountered,
Expand Down Expand Up @@ -1226,6 +1227,9 @@ void resolveVertexUnordered<let RAY_FLAGS : uint8_t>(
decalEmissiveRadiance = memory.emissiveRadiance;
}
#endif

emissiveRadiance *= 1.h/pathSelectionProbability;
decalEmissiveRadiance *= 1.h/pathSelectionProbability;
}

#if 0
Expand Down
1 change: 1 addition & 0 deletions src/dxvk/shaders/rtx/pass/raytrace_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ struct RaytraceArgs {
uint enableIndirectTranslucentShadows;
uint enableFirstBounceLobeProbabilityDithering;
uint enableUnorderedResolveInIndirectRays;
uint enableProbabilisticUnorderedResolveInIndirectRays;
uint enableUnorderedEmissiveParticlesInIndirectRays;
uint enableTransmissionApproximationInIndirectRays;
uint enableDecalMaterialBlending;
Expand Down

0 comments on commit b698be7

Please sign in to comment.