21
21
*/
22
22
#include " rtx_camera_manager.h"
23
23
24
- #include " rtx_matrix_helpers.h"
25
-
26
24
#include " dxvk_device.h"
27
25
28
26
namespace {
@@ -44,6 +42,7 @@ namespace dxvk {
44
42
45
43
void CameraManager::onFrameEnd () {
46
44
m_lastSetCameraType = CameraType::Unknown;
45
+ m_decompositionCache.clear ();
47
46
}
48
47
49
48
CameraType::Enum CameraManager::processCameraData (const DrawCallState& input) {
@@ -75,10 +74,7 @@ namespace dxvk {
75
74
}
76
75
77
76
// Get camera params
78
- float fov, aspectRatio, nearPlane, farPlane, shearX, shearY;
79
- bool isLHS;
80
- bool isReverseZ;
81
- decomposeProjection (input.getTransformData ().viewToProjection , aspectRatio, fov, nearPlane, farPlane, shearX, shearY, isLHS, isReverseZ);
77
+ DecomposeProjectionParams decomposeProjectionParams = getOrDecomposeProjection (input.getTransformData ().viewToProjection );
82
78
83
79
// Filter invalid cameras, extreme shearing
84
80
static auto isFovValid = [](float fovA) {
@@ -88,7 +84,7 @@ namespace dxvk {
88
84
return std::abs (fovA - cameraB.getFov ()) < kFovToleranceRadians ;
89
85
};
90
86
91
- if (std::abs (shearX) > 0 .01f || !isFovValid (fov)) {
87
+ if (std::abs (decomposeProjectionParams. shearX ) > 0 .01f || !isFovValid (decomposeProjectionParams. fov )) {
92
88
ONCE (Logger::warn (" [RTX] CameraManager: rejected an invalid camera" ));
93
89
return input.getCategoryFlags ().test (InstanceCategories::Sky) ? CameraType::Sky : CameraType::Unknown;
94
90
}
@@ -117,13 +113,13 @@ namespace dxvk {
117
113
cameraType = CameraType::RenderToTexture;
118
114
} else if (input.testCategoryFlags (InstanceCategories::Sky)) {
119
115
cameraType = CameraType::Sky;
120
- } else if (isViewModel (fov, input.maxZ , frameId)) {
116
+ } else if (isViewModel (decomposeProjectionParams. fov , input.maxZ , frameId)) {
121
117
cameraType = CameraType::ViewModel;
122
118
}
123
119
124
120
// Check fov consistency across frames
125
121
if (frameId > 0 ) {
126
- if (getCamera (cameraType).isValid (frameId - 1 ) && !areFovsClose (fov, getCamera (cameraType))) {
122
+ if (getCamera (cameraType).isValid (frameId - 1 ) && !areFovsClose (decomposeProjectionParams. fov , getCamera (cameraType))) {
127
123
ONCE (Logger::warn (" [RTX] CameraManager: FOV of a camera changed between frames" ));
128
124
}
129
125
}
@@ -148,7 +144,15 @@ namespace dxvk {
148
144
}
149
145
} else {
150
146
isCameraCut = camera.update (
151
- frameId, worldToView, viewToProjection, fov, aspectRatio, nearPlane,farPlane, isLHS);
147
+ frameId,
148
+ worldToView,
149
+ viewToProjection,
150
+ decomposeProjectionParams.fov ,
151
+ decomposeProjectionParams.aspectRatio ,
152
+ decomposeProjectionParams.nearPlane ,
153
+ decomposeProjectionParams.farPlane ,
154
+ decomposeProjectionParams.isLHS
155
+ );
152
156
}
153
157
154
158
@@ -173,13 +177,29 @@ namespace dxvk {
173
177
void CameraManager::processExternalCamera (CameraType::Enum type,
174
178
const Matrix4& worldToView,
175
179
const Matrix4& viewToProjection) {
176
- float fov, aspectRatio, nearPlane, farPlane, shearX, shearY;
177
- bool isLHS;
178
- bool isReverseZ;
179
- decomposeProjection (viewToProjection, aspectRatio, fov, nearPlane, farPlane, shearX, shearY, isLHS, isReverseZ);
180
+ DecomposeProjectionParams decomposeProjectionParams = getOrDecomposeProjection (viewToProjection);
180
181
181
182
getCamera (type).update (
182
183
m_device->getCurrentFrameId (),
183
- worldToView, viewToProjection, fov, aspectRatio, nearPlane, farPlane, isLHS);
184
+ worldToView,
185
+ viewToProjection,
186
+ decomposeProjectionParams.fov ,
187
+ decomposeProjectionParams.aspectRatio ,
188
+ decomposeProjectionParams.nearPlane ,
189
+ decomposeProjectionParams.farPlane ,
190
+ decomposeProjectionParams.isLHS );
184
191
}
192
+
193
+ DecomposeProjectionParams CameraManager::getOrDecomposeProjection (const Matrix4& viewToProjection) {
194
+ XXH64_hash_t projectionHash = XXH64 (&viewToProjection, sizeof (viewToProjection), 0 );
195
+ auto iter = m_decompositionCache.find (projectionHash);
196
+ if (iter != m_decompositionCache.end ()) {
197
+ return iter->second ;
198
+ }
199
+
200
+ DecomposeProjectionParams decomposeProjectionParams;
201
+ decomposeProjection (viewToProjection, decomposeProjectionParams);
202
+ m_decompositionCache.emplace (projectionHash, decomposeProjectionParams);
203
+ return decomposeProjectionParams;
204
+ }
185
205
} // namespace dxvk
0 commit comments