Skip to content

Commit e1b6c48

Browse files
Merge branch 'REMIX-4725-bug-fixes' into 'main'
[REMIX-4725] Fix several component related issues Closes REMIX-4725 See merge request lightspeedrtx/dxvk-remix-nv!1777
2 parents e6f1985 + a4a09f9 commit e1b6c48

23 files changed

+179
-101
lines changed

documentation/components/BoxProximity.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Box Proximity
22

3-
Calculates the signed distance from a world position to a mesh's bounding box\. Positive values indicate the point is inside the bounding box\. Note that the output is in object space\.
3+
Calculates the signed distance from a world position to a mesh's bounding box\. Positive values indicate the point is outside the bounding box\. Note that the output is in object space\.
44

55
## Component Information
66

@@ -67,7 +67,7 @@ Underlying Type: `Uint32`
6767

6868
### Signed Distance
6969

70-
Distance in object space to the nearest bounding box plane\. Positive when inside, negative when outside\. Outputs \-FLT\_MAX when no valid bounding box is found\.
70+
Distance in object space to the nearest bounding box plane\. Positive when outside, negative when inside\. Outputs FLT\_MAX when no valid bounding box is found\.
7171

7272

7373
### Activation Strength

documentation/components/InterpolateFloat.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Interpolate Float
22

3-
Interpolates a value from an input range to an output range with optional easing\. <br/>Combines normalization \(reverse LERP\), easing, and mapping \(LERP\) into a single component\. <br/><br/>Note input values outside of input range are valid, and that easing can lead to the output value being outside of the output range even when input is inside the input range\.<br/> Inverted ranges \(max < min\) are supported, but the results are undefined and may change without warning\.
3+
Interpolates a value from an input range to an output range with optional easing\. <br/>Combines normalization \(reverse LERP\), easing, and mapping \(LERP\) into a single component\. <br/><br/>Note input values outside of input range are valid, and that easing can lead to the output value being outside of the output range even when input is inside the input range\.<br/>Inverted input ranges \(Input Max < Input Min\) are supported \- the min/max will be swapped and the normalized value inverted\.
44

55
## Component Information
66

documentation/components/RtxOptionLayerAction.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Controls an RtxOptionLayer by name, allowing dynamic enable/disable, strength ad
1717
| enabled | Enabled | Bool | Input | true | Yes |
1818
| blendStrength | Blend Strength | Float | Input | 1\.0 | Yes |
1919
| blendThreshold | Blend Threshold | Float | Input | 0\.1 | Yes |
20-
| priority | Priority | Uint32 | Input | 100 | Yes |
20+
| priority | Priority | Uint32 | Input | 10000 | Yes |
2121

2222
### Config Path
2323

@@ -56,8 +56,8 @@ The priority for the option layer\. Higher values are blended onto lower values\
5656

5757
**Value Constraints:**
5858

59-
- **Minimum Value:** 0
60-
- **Maximum Value:** 4294967195
59+
- **Minimum Value:** 101
60+
- **Maximum Value:** 4294967294
6161

6262
## State Properties
6363

documentation/components/TextureHashChecker.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Texture Hash Checker
22

3-
Checks if a specific hash was used for material replacement in the current frame\.
3+
Checks if a specific texture hash was used for material replacement in the current frame\. This includes textures in all categories, including ignored textures\.
44

55
## Component Information
66

documentation/components/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This documentation provides detailed information about all available components
2929
| [Camera](Camera.md) | Outputs current camera properties including position, orientation vectors, and projection parameters\.\.\. | 1 |
3030
| [Keyboard Input](KeyboardInput.md) | Checks the state of a keyboard key or key combination using the same format as RTX options\. | 1 |
3131
| [Mesh Hash Checker](MeshHashChecker.md) | Checks if a specific mesh hash was processed in the current frame\. | 1 |
32-
| [Texture Hash Checker](TextureHashChecker.md) | Checks if a specific hash was used for material replacement in the current frame\. | 1 |
32+
| [Texture Hash Checker](TextureHashChecker.md) | Checks if a specific texture hash was used for material replacement in the current frame\. This incl\.\.\. | 1 |
3333
| [Time](Time.md) | Outputs the time in seconds since the component was created\. Can be paused and speed\-adjusted\. | 1 |
3434

3535
## Statistics

src/d3d9/d3d9_rtx.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,15 @@ namespace dxvk {
10621062
if (d3d9State().textures[firstStage]) {
10631063
m_activeDrawCallState.setupCategoriesForTexture();
10641064

1065+
// Track the texture hash before checking if it should be ignored
1066+
// This ensures we track all textures sent by the game, not just the ones that are actually rendered.
1067+
const XXH64_hash_t textureHash = m_activeDrawCallState.materialData.getColorTexture().getImageHash();
1068+
if (textureHash != kEmptyHash) {
1069+
m_parent->EmitCs([textureHash](DxvkContext* ctx) {
1070+
static_cast<RtxContext*>(ctx)->getSceneManager().trackReplacementMaterialHash(textureHash);
1071+
});
1072+
}
1073+
10651074
// Check if an ignore texture is bound
10661075
if (m_activeDrawCallState.getCategoryFlags().test(InstanceCategories::Ignore)) {
10671076
return false;

src/dxvk/rtx_render/graph/components/box_proximity.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ namespace components {
4848
#define LIST_STATES(X)
4949

5050
#define LIST_OUTPUTS(X) \
51-
X(RtComponentPropertyType::Float, 0.0f, signedDistance, "Signed Distance", "Distance in object space to the nearest bounding box plane. Positive when inside, negative when outside. Outputs -FLT_MAX when no valid bounding box is found.") \
51+
X(RtComponentPropertyType::Float, 0.0f, signedDistance, "Signed Distance", "Distance in object space to the nearest bounding box plane. Positive when outside, negative when inside. Outputs FLT_MAX when no valid bounding box is found.") \
5252
X(RtComponentPropertyType::Float, 0.0f, activationStrength, "Activation Strength", "Normalized 0-1 value: 0 when on bounding box surface, 1 when at max distance inside (with easing applied).")
5353

5454
REMIX_COMPONENT( \
5555
/* the Component name */ BoxProximity, \
5656
/* the UI name */ "Box Proximity", \
5757
/* the UI categories */ "Sense", \
58-
/* the doc string */ "Calculates the signed distance from a world position to a mesh's bounding box. Positive values indicate the point is inside the bounding box. Note that the output is in object space.", \
58+
/* the doc string */ "Calculates the signed distance from a world position to a mesh's bounding box. Positive values indicate the point is outside the bounding box. Note that the output is in object space.", \
5959
/* the version number */ 1, \
6060
LIST_INPUTS, LIST_STATES, LIST_OUTPUTS);
6161

@@ -64,7 +64,7 @@ REMIX_COMPONENT( \
6464
#undef LIST_OUTPUTS
6565

6666
// Calculate signed distance from point to axis-aligned bounding box
67-
// Returns positive distance when inside the box, negative when outside
67+
// Returns positive distance when outside the box, negative when inside
6868
static float calculateSignedDistanceToAABB(const Vector3& point, const AxisAlignedBoundingBox& aabb) {
6969
// bounding box already validated in updateRange function
7070

@@ -78,14 +78,14 @@ static float calculateSignedDistanceToAABB(const Vector3& point, const AxisAlign
7878
// If the point is inside the box, all distances are negative
7979
// The signed distance is the maximum (least negative) distance to any face
8080
if (distToFaces.x <= 0.0f && distToFaces.y <= 0.0f && distToFaces.z <= 0.0f) {
81-
// Inside the box - return the distance to the nearest face (positive)
82-
return -std::max(distToFaces.x, std::max(distToFaces.y, distToFaces.z));
81+
// Inside the box - return the distance to the nearest face (negative)
82+
return std::max(distToFaces.x, std::max(distToFaces.y, distToFaces.z));
8383
} else {
84-
// Outside the box - return the distance to the nearest corner/edge/face (negative)
84+
// Outside the box - return the distance to the nearest corner/edge/face (positive)
8585
// For points outside, we need the Euclidean distance to the nearest point on the box
8686
Vector3 clampedPoint = clamp(point, aabb.minPos, aabb.maxPos);
8787
Vector3 diff = point - clampedPoint;
88-
return -length(diff);
88+
return length(diff);
8989
}
9090
}
9191

@@ -142,7 +142,7 @@ void BoxProximity::updateRange(const Rc<DxvkContext>& context, const size_t star
142142

143143
if (unlikely(signedDistance == FLT_MAX)) {
144144
ONCE(Logger::err(str::format("BoxProximity: No valid bounding box found.")));
145-
m_signedDistance[i] = -FLT_MAX;
145+
m_signedDistance[i] = FLT_MAX;
146146
m_activationStrength[i] = 0.0f;
147147
continue;
148148
}

src/dxvk/rtx_render/graph/components/interpolate_float.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ REMIX_COMPONENT( \
5353
"\nCombines normalization (reverse LERP), easing, and mapping (LERP) into a single component. " \
5454
"\n\nNote input values outside of input range are valid, and that easing can lead to the output value being " \
5555
"outside of the output range even when input is inside the input range." \
56-
"\n Inverted ranges (max < min) are supported, but the results are undefined and may change without warning.", \
56+
"\nInverted input ranges (Input Max < Input Min) are supported - the min/max will be swapped and the normalized value inverted.", \
5757
/* the version number */ 1, \
5858
LIST_INPUTS, LIST_STATES, LIST_OUTPUTS);
5959

@@ -65,14 +65,30 @@ void InterpolateFloat::updateRange(const Rc<DxvkContext>& context, const size_t
6565
for (size_t i = start; i < end; i++) {
6666
// Step 1: Normalize input value to 0-1 range (reverse LERP / float_to_strength)
6767
float normalizedValue = m_value[i];
68-
if (m_inputMax[i] == m_inputMin[i]) {
68+
bool shouldInvert = false;
69+
70+
// Check if the range is inverted
71+
float minVal = m_inputMin[i];
72+
float maxVal = m_inputMax[i];
73+
if (minVal > maxVal) {
74+
// Swap min and max
75+
std::swap(minVal, maxVal);
76+
shouldInvert = true;
77+
}
78+
79+
if (maxVal == minVal) {
6980
ONCE(Logger::err(str::format("InterpolateFloat: Input Min and Input Max are the same. Setting normalized value to 0.0f. Input Min: ", m_inputMin[i], " Input Max: ", m_inputMax[i])));
7081
normalizedValue = 0.0f; // Avoid division by zero
7182
} else {
7283
if (m_clampInput[i]) {
73-
normalizedValue = clamp(normalizedValue, m_inputMin[i], m_inputMax[i]);
84+
normalizedValue = clamp(normalizedValue, minVal, maxVal);
85+
}
86+
normalizedValue = (normalizedValue - minVal) / (maxVal - minVal);
87+
88+
// Invert normalized value if the range was inverted
89+
if (shouldInvert) {
90+
normalizedValue = 1.0f - normalizedValue;
7491
}
75-
normalizedValue = (normalizedValue - m_inputMin[i]) / (m_inputMax[i] - m_inputMin[i]);
7692
}
7793

7894
// cache in a const value to avoid double branch
@@ -99,4 +115,3 @@ void InterpolateFloat::updateRange(const Rc<DxvkContext>& context, const size_t
99115

100116
} // namespace components
101117
} // namespace dxvk
102-

src/dxvk/rtx_render/graph/components/rtx_option_layer_action.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
namespace dxvk {
2929
namespace components {
3030

31-
static constexpr uint32_t kMaxComponentRtxOptionLayerPriority = ::dxvk::RtxOptionLayer::s_runtimeOptionLayerPriority - ::dxvk::RtxOptionLayer::s_userOptionLayerOffset;
31+
static constexpr uint32_t kMaxComponentRtxOptionLayerPriority = dxvk::RtxOptionLayer::s_runtimeOptionLayerPriority - 1;
32+
static constexpr uint32_t kMinComponentRtxOptionLayerPriority = RtxOptionLayer::s_userOptionLayerOffset + 1;
33+
static constexpr uint32_t kDefaultComponentRtxOptionLayerPriority = 10000;
3234

3335

3436
#define LIST_INPUTS(X) \
@@ -38,7 +40,7 @@ static constexpr uint32_t kMaxComponentRtxOptionLayerPriority = ::dxvk::RtxOptio
3840
"\n\nLowest priority layer uses LERP to blend with default value, then each higher priority layer uses LERP to blend with the previous layer's result." \
3941
"\n\nIf multiple components control the same layer, the MAX blend strength will be used.", property.minValue = 0.0f, property.maxValue = 1.0f, property.optional = true) \
4042
X(RtComponentPropertyType::Float, 0.1f, blendThreshold, "Blend Threshold", "The blend threshold for non-float options (0.0 to 1.0). Non-float options are only applied when blend strength exceeds this threshold. If multiple components control the same layer, the MINIMUM blend threshold will be used.", property.minValue = 0.0f, property.maxValue = 1.0f, property.optional = true) \
41-
X(RtComponentPropertyType::Uint32, 100, priority, "Priority", "The priority for the option layer. Higher values are blended onto lower values. Must be unique across all layers.", property.minValue = 0, property.maxValue = kMaxComponentRtxOptionLayerPriority, property.optional = true)
43+
X(RtComponentPropertyType::Uint32, kDefaultComponentRtxOptionLayerPriority, priority, "Priority", "The priority for the option layer. Higher values are blended onto lower values. Must be unique across all layers.", property.minValue = RtxOptionLayer::s_userOptionLayerOffset + 1, property.maxValue = kMaxComponentRtxOptionLayerPriority, property.optional = true)
4244

4345
#define LIST_STATES(X) \
4446
X(RtComponentPropertyType::Uint64, 0, cachedLayerPtr, "", "Cached pointer to the RtxOptionLayer (internal use).")
@@ -85,10 +87,15 @@ class RtxOptionLayerAction : public RtRegisteredComponentBatch<RtxOptionLayerAct
8587
#undef LIST_OUTPUTS
8688

8789
void RtxOptionLayerAction::initializeInstance(const Rc<DxvkContext>& context, const size_t index) {
90+
uint32_t priority = m_priority[index];
91+
clamp(priority, kMinComponentRtxOptionLayerPriority, kMaxComponentRtxOptionLayerPriority);
92+
93+
// TODO if the priority is left unset, we need to automatically assign a priority.
94+
8895
// Acquire layer through the manager
8996
const ::dxvk::RtxOptionLayer* layer = dxvk::RtxOptionLayerManager::acquireLayer(
9097
m_configPath[index],
91-
m_priority[index],
98+
priority,
9299
1.0f, // Default blend strength (will be updated in updateRange)
93100
0.1f // Default blend threshold (will be updated in updateRange)
94101
);
@@ -123,21 +130,20 @@ void RtxOptionLayerAction::updateRange(const Rc<DxvkContext>& context, const siz
123130
// Request enabled state for this frame
124131
// If multiple components control this layer, it will be enabled if ANY of them request it
125132
cachedLayer->requestEnabled(m_enabled[i]);
126-
127-
// Request blend strength for this frame
128-
// If multiple components control this layer, the MAX blend strength will be used
129-
const float targetStrength = std::clamp(m_blendStrength[i], 0.0f, 1.0f);
130-
cachedLayer->requestBlendStrength(targetStrength);
131-
132-
// Request blend threshold for this frame
133-
// If multiple components control this layer, the MIN blend threshold will be used
134-
const float targetThreshold = std::clamp(m_blendThreshold[i], 0.0f, 1.0f);
135-
cachedLayer->requestBlendThreshold(targetThreshold);
133+
134+
if (m_enabled[i]) {
135+
// Request blend strength for this frame
136+
// If multiple components control this layer, the MAX blend strength will be used
137+
const float targetStrength = std::clamp(m_blendStrength[i], 0.0f, 1.0f);
138+
cachedLayer->requestBlendStrength(targetStrength);
139+
140+
// Request blend threshold for this frame
141+
// If multiple components control this layer, the MIN blend threshold will be used
142+
const float targetThreshold = std::clamp(m_blendThreshold[i], 0.0f, 1.0f);
143+
cachedLayer->requestBlendThreshold(targetThreshold);
144+
}
136145
}
137146
}
138147

139148
} // namespace components
140149
} // namespace dxvk
141-
142-
143-

src/dxvk/rtx_render/graph/components/texture_hash_checker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ REMIX_COMPONENT( \
4141
/* the Component name */ TextureHashChecker, \
4242
/* the UI name */ "Texture Hash Checker", \
4343
/* the UI categories */ "Sense", \
44-
/* the doc string */ "Checks if a specific hash was used for material replacement in the current frame.", \
44+
/* the doc string */ "Checks if a specific texture hash was used for material replacement in the current frame. This includes textures in all categories, including ignored textures.", \
4545
/* the version number */ 1, \
4646
LIST_INPUTS, LIST_STATES, LIST_OUTPUTS);
4747

@@ -58,7 +58,7 @@ void TextureHashChecker::updateRange(const Rc<DxvkContext>& context, const size_
5858
const uint64_t targetHash = m_textureHash[i];
5959

6060
// Check if the texture hash was used for material replacement this frame
61-
uint32_t count = sceneManager.getMaterialHashUsageCount(targetHash);
61+
uint32_t count = sceneManager.getReplacementMaterialHashUsageCount(targetHash);
6262
bool isUsed = count > 0;
6363

6464
m_isUsed[i] = isUsed;

0 commit comments

Comments
 (0)