Skip to content

Commit 1782430

Browse files
Merge branch 'component-strings-and-asset-paths' into 'main'
[REMIX-4538] Add String and AssetPath component property types See merge request lightspeedrtx/dxvk-remix-nv!1674
2 parents 098a7cd + b0631f6 commit 1782430

File tree

8 files changed

+246
-61
lines changed

8 files changed

+246
-61
lines changed

src/dxvk/rtx_render/graph/rtx_graph_md_writer.cpp

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@
2828

2929
namespace dxvk {
3030
namespace {
31+
32+
// Helper function to escape markdown special characters
33+
std::string escapeMarkdown(const std::string& input) {
34+
std::string output;
35+
output.reserve(input.size());
36+
for (char c : input) {
37+
switch (c) {
38+
case '*': output += "\\*"; break;
39+
case '_': output += "\\_"; break;
40+
case '`': output += "\\`"; break;
41+
case '#': output += "\\#"; break;
42+
case '+': output += "\\+"; break;
43+
case '-': output += "\\-"; break;
44+
case '.': output += "\\."; break;
45+
case '!': output += "\\!"; break;
46+
case '[': output += "\\["; break;
47+
case ']': output += "\\]"; break;
48+
case '(': output += "\\("; break;
49+
case ')': output += "\\)"; break;
50+
case '\n': output += "<br/>"; break; // Convert newlines to HTML line breaks for table compatibility
51+
case '\r': break; // Skip carriage returns
52+
default: output += c; break;
53+
}
54+
}
55+
return output;
56+
}
57+
3158
// Helper function to get default value as readable string
3259
std::string getDefaultValueAsString(const RtComponentPropertyValue& value, RtComponentPropertyType type) {
3360
switch (type) {
@@ -60,6 +87,10 @@ std::string getDefaultValueAsString(const RtComponentPropertyValue& value, RtCom
6087
return std::to_string(std::get<uint32_t>(value));
6188
case RtComponentPropertyType::Uint64:
6289
return std::to_string(std::get<uint64_t>(value));
90+
case RtComponentPropertyType::String:
91+
return "\"" + escapeMarkdown(std::get<std::string>(value)) + "\"";
92+
case RtComponentPropertyType::AssetPath:
93+
return "\"" + escapeMarkdown(std::get<std::string>(value)) + "\"";
6394
case RtComponentPropertyType::Prim:
6495
// Prim references don't use the default value field,
6596
// as it isn't really applicable.
@@ -68,31 +99,6 @@ std::string getDefaultValueAsString(const RtComponentPropertyValue& value, RtCom
6899
return "None";
69100
}
70101

71-
// Helper function to escape markdown special characters
72-
std::string escapeMarkdown(const std::string& input) {
73-
std::string output;
74-
for (char c : input) {
75-
switch (c) {
76-
case '*': output += "\\*"; break;
77-
case '_': output += "\\_"; break;
78-
case '`': output += "\\`"; break;
79-
case '#': output += "\\#"; break;
80-
case '+': output += "\\+"; break;
81-
case '-': output += "\\-"; break;
82-
case '.': output += "\\."; break;
83-
case '!': output += "\\!"; break;
84-
case '[': output += "\\["; break;
85-
case ']': output += "\\]"; break;
86-
case '(': output += "\\("; break;
87-
case ')': output += "\\)"; break;
88-
case '\n': output += "<br/>"; break; // Convert newlines to HTML line breaks for table compatibility
89-
case '\r': break; // Skip carriage returns
90-
default: output += c; break;
91-
}
92-
}
93-
return output;
94-
}
95-
96102
// Helper function to write a property table row
97103
void writePropertyTableRow(std::ofstream& outputFile, const RtComponentPropertySpec& prop) {
98104
outputFile << "| " << escapeMarkdown(prop.name) << " | ";

src/dxvk/rtx_render/graph/rtx_graph_ogn_writer.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,25 @@
2727

2828
namespace dxvk {
2929
namespace {
30+
// Helper function to escape JSON strings
31+
std::string escapeJsonString(const std::string& input) {
32+
std::string output;
33+
output.reserve(input.size());
34+
for (char c : input) {
35+
switch (c) {
36+
case '"': output += "\\\""; break;
37+
case '\\': output += "\\\\"; break;
38+
case '\b': output += "\\b"; break;
39+
case '\f': output += "\\f"; break;
40+
case '\n': output += "\\n"; break;
41+
case '\r': output += "\\r"; break;
42+
case '\t': output += "\\t"; break;
43+
default: output += c; break;
44+
}
45+
}
46+
return output;
47+
}
48+
3049
// Helper function to convert RtComponentPropertyType to OGN type string
3150
std::string propertyTypeToOgnType(RtComponentPropertyType type) {
3251
switch (type) {
@@ -40,8 +59,10 @@ std::string propertyTypeToOgnType(RtComponentPropertyType type) {
4059
case RtComponentPropertyType::Uint32: return "uint";
4160
case RtComponentPropertyType::Uint64: return "uint64";
4261
case RtComponentPropertyType::Prim: return "target"; // USD Relationship to a prim
43-
default: return "float"; // Default fallback
62+
case RtComponentPropertyType::String: return "string";
63+
case RtComponentPropertyType::AssetPath: return "asset";
4464
}
65+
return "unknown";
4566
}
4667

4768
// Helper function to get default value as JSON string
@@ -76,31 +97,17 @@ std::string getDefaultValueAsJson(const RtComponentPropertyValue& value, RtCompo
7697
return std::to_string(std::get<uint32_t>(value));
7798
case RtComponentPropertyType::Uint64:
7899
return std::to_string(std::get<uint64_t>(value));
100+
case RtComponentPropertyType::String:
101+
return "\"" + escapeJsonString(std::get<std::string>(value)) + "\"";
102+
case RtComponentPropertyType::AssetPath:
103+
return "\"" + escapeJsonString(std::get<std::string>(value)) + "\"";
79104
case RtComponentPropertyType::Prim:
80105
// Target relationships don't typically have default values in OGN
81106
return "null";
82107
}
83108
return "null";
84109
}
85110

86-
// Helper function to escape JSON strings
87-
std::string escapeJsonString(const std::string& input) {
88-
std::string output;
89-
for (char c : input) {
90-
switch (c) {
91-
case '"': output += "\\\""; break;
92-
case '\\': output += "\\\\"; break;
93-
case '\b': output += "\\b"; break;
94-
case '\f': output += "\\f"; break;
95-
case '\n': output += "\\n"; break;
96-
case '\r': output += "\\r"; break;
97-
case '\t': output += "\\t"; break;
98-
default: output += c; break;
99-
}
100-
}
101-
return output;
102-
}
103-
104111
// Helper function to write a property to the OGN schema
105112
void writePropertyToOGN(std::ofstream& outputFile, const RtComponentPropertySpec& prop, bool isLast) {
106113
outputFile << " \"" << escapeJsonString(prop.name) << "\": {" << std::endl;

src/dxvk/rtx_render/graph/rtx_graph_types.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ std::ostream& operator << (std::ostream& os, RtComponentPropertyType type) {
209209
case RtComponentPropertyType::Uint32: return os << "Uint32";
210210
case RtComponentPropertyType::Uint64: return os << "Uint64";
211211
case RtComponentPropertyType::Prim: return os << "Prim";
212+
case RtComponentPropertyType::String: return os << "String";
213+
case RtComponentPropertyType::AssetPath: return os << "AssetPath";
212214
}
213215
return os << static_cast<int32_t>(type);
214216
}
@@ -244,6 +246,9 @@ RtComponentPropertyValue propertyValueFromString(const std::string& str, const R
244246
return propertyValueForceType<uint64_t>(std::stoull(str));
245247
case RtComponentPropertyType::Prim:
246248
return propertyValueForceType<uint32_t>(std::stoull(str));
249+
case RtComponentPropertyType::String:
250+
case RtComponentPropertyType::AssetPath:
251+
return str;
247252
}
248253
Logger::err(str::format("Unknown property type in propertyValueFromString. type: ", type, ", string: ", str));
249254
assert(false && "Unknown property type in propertyValueFromString");
@@ -268,6 +273,8 @@ RtComponentPropertyVector propertyVectorFromType(const RtComponentPropertyType t
268273
case RtComponentPropertyType::Uint32: return std::vector<RtComponentPropertyTypeToCppType<RtComponentPropertyType::Uint32>>{};
269274
case RtComponentPropertyType::Uint64: return std::vector<RtComponentPropertyTypeToCppType<RtComponentPropertyType::Uint64>>{};
270275
case RtComponentPropertyType::Prim: return std::vector<RtComponentPropertyTypeToCppType<RtComponentPropertyType::Prim>>{};
276+
case RtComponentPropertyType::String: return std::vector<std::string>{};
277+
case RtComponentPropertyType::AssetPath: return std::vector<std::string>{};
271278
}
272279
assert(false && "Unknown property type in propertyVectorFromType");
273280
return std::vector<RtComponentPropertyTypeToCppType<RtComponentPropertyType::Float>>{}; // fallback

src/dxvk/rtx_render/graph/rtx_graph_types.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,14 @@ enum class RtComponentPropertyType {
5555
Int32,
5656
Uint32,
5757
Uint64,
58+
String,
59+
AssetPath,
5860

5961
// Default Value is ignored for relationships. It's safe to just use 0.
6062
Prim,
6163

6264
// TODO should we support lists of any of the above types.
6365
// TODO should Hash be a separate type? it's just uint64_t under the hood, but could be displayed differently.
64-
// TODO should we support strings? asset paths?
6566
// TODO support generic types (i.e. number, or numbersAndVectors)
6667

6768
// NOTE: Places to change when adding a new case:
@@ -70,6 +71,8 @@ enum class RtComponentPropertyType {
7071
// `RtComponentPropertyTypeToCppType` in rtx_graph_types.h.
7172
// `RtComponentPropertyValue` variant in rtx_graph_types.h,
7273
// `RtComponentPropertyVector` variant in rtx_graph_types.h,
74+
// `GraphUsdParser::getPropertyValue` in rtx_graph_usd_parser.cpp
75+
// `TestComponent` in test_component.h, and the unit tests it is used in.
7376
};
7477
std::ostream& operator << (std::ostream& os, RtComponentPropertyType e);
7578

@@ -87,6 +90,8 @@ template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::
8790
template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::Uint32> { using Type = uint32_t; };
8891
template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::Uint64> { using Type = uint64_t; };
8992
template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::Prim> { using Type = uint32_t; };
93+
template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::String> { using Type = std::string; };
94+
template<> struct RtComponentPropertyTypeToCppTypeImpl<RtComponentPropertyType::AssetPath> { using Type = std::string; };
9095

9196
template< RtComponentPropertyType propertyType >
9297
using RtComponentPropertyTypeToCppType = typename RtComponentPropertyTypeToCppTypeImpl<propertyType>::Type;
@@ -106,7 +111,8 @@ using RtComponentPropertyValue = std::variant<
106111
Vector4,
107112
int32_t,
108113
uint32_t,
109-
uint64_t
114+
uint64_t,
115+
std::string
110116
>;
111117

112118
using RtComponentPropertyVector = std::variant<
@@ -118,7 +124,8 @@ using RtComponentPropertyVector = std::variant<
118124
std::vector<Vector4>,
119125
std::vector<int32_t>,
120126
std::vector<uint32_t>,
121-
std::vector<uint64_t>
127+
std::vector<uint64_t>,
128+
std::vector<std::string>
122129
>;
123130

124131
RtComponentPropertyValue propertyValueFromString(const std::string& str, const RtComponentPropertyType type);

src/dxvk/rtx_render/graph/rtx_graph_usd_parser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ RtComponentPropertyValue GraphUsdParser::getPropertyValue(const pxr::UsdAttribut
350350
return getPropertyValue<uint32_t>(value, spec);
351351
case RtComponentPropertyType::Uint64:
352352
return getPropertyValue<uint64_t>(value, spec);
353+
case RtComponentPropertyType::String:
354+
return getPropertyValue<std::string>(value, spec);
355+
case RtComponentPropertyType::AssetPath:
356+
return getPropertyValue<std::string>(value, spec);
353357
case RtComponentPropertyType::Prim:
354358
throw DxvkError(str::format("Prim target properties should be UsdRelationships, not UsdAttributes."));
355359
return spec.defaultValue;

src/dxvk/rtx_render/graph/rtx_graph_usd_parser.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,12 @@ class GraphUsdParser {
8888
return propertyValueForceType<uint8_t>(value.Get<T>());
8989
}
9090
return value.Get<T>();
91+
} else if (constexpr (std::is_same_v<T, std::string>) && value.IsHolding<pxr::SdfAssetPath>()) {
92+
return value.Get<pxr::SdfAssetPath>().GetAssetPath();
9193
} else if (value.IsHolding<pxr::TfToken>()) {
94+
// Note: holds_alternative<bool> is a compiler error, so this constexpr check is needed.
9295
if constexpr (!std::is_same_v<T, bool>) {
93-
if ( spec.enumValues.size() > 0) {
96+
if (spec.enumValues.size() > 0) {
9497
// If the property has enum values, we need to look up the value in the enum values map.
9598
auto iter = spec.enumValues.find(value.Get<pxr::TfToken>().GetString());
9699
if (iter != spec.enumValues.end()) {

tests/rtx/unit/graph/test_component.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ enum class TestEnum : uint32_t {
4343
X(RtComponentPropertyType::Uint32, 1, inputUint32, "Input Uint32", "test for Uint32") \
4444
X(RtComponentPropertyType::Uint64, 1, inputUint64, "Input Uint64", "test for Uint64") \
4545
X(RtComponentPropertyType::Prim, 101, inputPrim, "Input Prim", "test for Prim") \
46+
X(RtComponentPropertyType::String, std::string("test_string"), inputString, "Input String", "test for String") \
47+
X(RtComponentPropertyType::AssetPath, std::string("/path/to/asset.usd"), inputAssetPath, "Input AssetPath", "test for AssetPath") \
4648
X(RtComponentPropertyType::Uint32, 1, inputUint32Enum, "Input Enum", "test for Uint32 as enum", \
47-
property.enumValues = { {"One", {TestEnum::One, "The first case"}}, {"Two", {TestEnum::Two, "The second case"}} }) \
49+
property.enumValues = { {"One", {TestEnum::One, "The first case"}}, {"Two", {TestEnum::Two, "The second case"}} })
4850

4951
#define LIST_STATES(X) \
5052
X(RtComponentPropertyType::Bool, false, stateBool, "", "test for Bool") \
@@ -57,6 +59,8 @@ enum class TestEnum : uint32_t {
5759
X(RtComponentPropertyType::Uint32, 2, stateUint32, "", "test for Uint32") \
5860
X(RtComponentPropertyType::Uint64, 2, stateUint64, "", "test for Uint64") \
5961
X(RtComponentPropertyType::Prim, 102, statePrim, "", "test for Prim") \
62+
X(RtComponentPropertyType::String, std::string("state_string"), stateString, "", "test for String") \
63+
X(RtComponentPropertyType::AssetPath, std::string("/path/to/state/asset.usd"), stateAssetPath, "", "test for AssetPath") \
6064
X(RtComponentPropertyType::Uint32, 2, stateUint32Enum, "", "test for Uint32 as enum", \
6165
property.enumValues = { {"One", {TestEnum::One, "The first case"}}, {"Two", {TestEnum::Two, "The second case"}} })
6266

@@ -71,6 +75,8 @@ enum class TestEnum : uint32_t {
7175
X(RtComponentPropertyType::Uint32, 3, outputUint32, "Output Uint32", "test for Uint32") \
7276
X(RtComponentPropertyType::Uint64, 3, outputUint64, "Output Uint64", "test for Uint64") \
7377
X(RtComponentPropertyType::Prim, 103, outputPrim, "Output Prim", "test for Prim") \
78+
X(RtComponentPropertyType::String, std::string("output_string"), outputString, "Output String", "test for String") \
79+
X(RtComponentPropertyType::AssetPath, std::string("/path/to/output/asset.usd"), outputAssetPath, "Output AssetPath", "test for AssetPath") \
7480
X(RtComponentPropertyType::Uint32, 3, outputUint32Enum, "Output Enum", "test for Uint32 as enum", \
7581
property.enumValues = { {"One", {TestEnum::One, "The first case"}}, {"Two", {TestEnum::Two, "The second case"}} })
7682

@@ -100,6 +106,8 @@ void TestComponent::updateRange(const Rc<DxvkContext>& context, const size_t sta
100106
m_stateUint32[i] = m_inputUint32[i];
101107
m_stateUint64[i] = m_inputUint64[i];
102108
m_statePrim[i] = m_inputPrim[i];
109+
m_stateString[i] = m_inputString[i];
110+
m_stateAssetPath[i] = m_inputAssetPath[i];
103111
m_stateUint32Enum[i] = m_inputUint32Enum[i];
104112
}
105113
m_outputBool[i] = m_stateBool[i];
@@ -112,6 +120,8 @@ void TestComponent::updateRange(const Rc<DxvkContext>& context, const size_t sta
112120
m_outputUint32[i] = m_stateUint32[i];
113121
m_outputUint64[i] = m_stateUint64[i];
114122
m_outputPrim[i] = m_statePrim[i];
123+
m_outputString[i] = m_stateString[i];
124+
m_outputAssetPath[i] = m_stateAssetPath[i];
115125
m_outputUint32Enum[i] = m_stateUint32Enum[i];
116126
}
117127
}

0 commit comments

Comments
 (0)